MIPS,位于堆栈中的字符串中出现的次数
MIPS, Number of occurrences in a string located in the stack
我在 MIPS 汇编中有一个练习要解决(我有一些疑问但其他事情很清楚)但是我在编写它的代码时遇到了一些问题。练习问我:
编写一个程序,从键盘获取一个字符串,计算出现次数较多的字符的出现次数并显示出来。
我如何检查所有 26 个字符并找出谁的出现次数更高?
示例:
给我一个字符串:Hello world!
出现次数较多的字符是:l
非常感谢未来的回答。
P.s。
这是我的第一部分:
#First message
li $v0, 4
la $a0, mess
syscall
#Stack space allocated
addi $sp, $sp, -257
#Read the string
move $a0, $sp
li $a1, 257
li $v0, 8
syscall
由于这是您的任务,我将把 MIPS 汇编实现留给您。我将用更高级的语言向您展示代码的逻辑:
// You'd keep these variables in some MIPS registers of your choice
int c, i, count, max_count=0;
char max_char;
// Iterate over all ASCII character codes
for (c = 0; c < 128; c+=1) {
count = 0;
// Count the number of occurences of this character in the string
for (i = 0; string[i]!=0; i+=1) {
if (string[i] == c) count++;
}
// Was is greater than the current max?
if (count > max_count) {
max_count = count;
max_char = c;
}
}
// max_char now hold the ASCII code of the character with the highest number
// of occurences, and max_count hold the number of times that character was
// found in the string.
@Michael,我看到你在发帖前回答了,我只是想用更详细的答案重复一遍。如果您自己编辑以添加更多解释,那么我将删除我的。我没有直接编辑你的,因为你发帖的时候我已经编辑到一半了。无论如何:
@Marco:
您可以创建一个包含 26 个计数器(初始化为 0)的临时数组。
每个计数器对应每个字母(即每个字母出现的次数)。例如 counter[0]
对应字母 'a' 的出现次数, counter[1]
对应字母 'b' 等...
然后遍历输入字符序列中的每个字符,并对每个字符执行:
a) 获取字符在counter
数组中的索引。
b) 将 counter["obtained index"]
增加 1。
要获取字符的索引,您可以执行以下操作:
a) 首先确保字符不是大写,即只允许 'a' 到 'z' 而不是 'A' 到 'Z'。如果不是,请转换它。
b) 从字符中减去字母'a'。这样 'a'-'a' 给出 0,'b'-'a' 给出 1,'c'-'a' 给出 2,等等...
我会用C语言演示,因为这是你在MIPS上的练习(我的意思是目标是学习MIPS汇编语言):
#include <stdio.h>
int main()
{
//Maximum length of string:
int stringMaxLength = 100;
//Create string in stack. Size of string is length+1 to
//allow the '[=10=]' character to mark the end of the string.
char str[stringMaxLength + 1];
//Read a string of maximum stringMaxLength characters:
puts("Enter string:");
scanf("%*s", stringMaxLength, str);
fflush(stdin);
//Create array of counters in stack:
int counter[26];
//Initialize the counters to 0:
int i;
for (i=0; i<26; ++i)
counter[i] = 0;
//Main counting loop:
for (i=0; str[i] != '[=10=]'; ++i)
{
char tmp = str[i]; //Storing of str[i] in tmp, to write tmp if needed,
//instead of writing str[i] itself. Optional operation in this particular case.
if (tmp >= 'A' && tmp <= 'Z') //If the current character is upper:
tmp = tmp + 32; //Convert the character to lower.
if (tmp >= 'a' && tmp <='z') //If the character is a lower letter:
{
//Obtain the index of the letter in the array:
int index = tmp - 'a';
//Increment its counter by 1:
counter[index] = counter[index] + 1;
}
//Else if the chacacter is not a lower letter by now, we ignore it,
//or we could inform the user, for example, or we could ignore the
//whole string itself as invalid..
}
//Now find the maximum occurences of a letter:
int indexOfMaxCount = 0;
int maxCount = counter[0];
for (i=1; i<26; ++i)
if (counter[i] > maxCount)
{
maxCount = counter[i];
indexOfMaxCount = i;
}
//Convert the indexOfMaxCount back to the character it corresponds to:
char maxChar = 'a' + indexOfMaxCount;
//Inform the user of the letter with maximum occurences:
printf("Maximum %d occurences for letter '%c'.\n", maxCount, maxChar);
return 0;
}
如果你不明白为什么我把大写字母加32转换成小写字母,那么请继续阅读:
每个字符在内存中对应一个整数值,当你对字符进行算术运算时,就相当于将它们变成编码中对应的数字table。
encoding 只是一个 table,它将这些字母与数字匹配。
例如 'a' 对应 ASCII encoding/decoding/table.
中的数字 97
例如 'b' 对应 ASCII encoding/decoding/table 中的数字 98。
所以'a'+1给出97+1=98就是字符'b'。它们都是内存中的数字,区别在于你如何表示(解码)它们。同样的table的编码,当然也用于解码。
示例:
printf("%c", 'a'); //Prints 'a'.
printf("%d", (int) 'a'); //Prints '97'.
printf("%c", (char) 97); //Prints 'a'.
printf("%d", 97); //Prints '97'.
printf("%d", (int) 'b'); //Prints '98'.
printf("%c", (char) (97 + 1)); //Prints 'b'.
printf("%c", (char) ( ((int) 'a') + 1 ) ); //Prints 'b'.
//Etc...
//All the casting in the above examples is just for demonstration,
//it would work without them also, in this case.
我在 MIPS 汇编中有一个练习要解决(我有一些疑问但其他事情很清楚)但是我在编写它的代码时遇到了一些问题。练习问我: 编写一个程序,从键盘获取一个字符串,计算出现次数较多的字符的出现次数并显示出来。
我如何检查所有 26 个字符并找出谁的出现次数更高?
示例: 给我一个字符串:Hello world! 出现次数较多的字符是:l
非常感谢未来的回答。
P.s。 这是我的第一部分:
#First message
li $v0, 4
la $a0, mess
syscall
#Stack space allocated
addi $sp, $sp, -257
#Read the string
move $a0, $sp
li $a1, 257
li $v0, 8
syscall
由于这是您的任务,我将把 MIPS 汇编实现留给您。我将用更高级的语言向您展示代码的逻辑:
// You'd keep these variables in some MIPS registers of your choice
int c, i, count, max_count=0;
char max_char;
// Iterate over all ASCII character codes
for (c = 0; c < 128; c+=1) {
count = 0;
// Count the number of occurences of this character in the string
for (i = 0; string[i]!=0; i+=1) {
if (string[i] == c) count++;
}
// Was is greater than the current max?
if (count > max_count) {
max_count = count;
max_char = c;
}
}
// max_char now hold the ASCII code of the character with the highest number
// of occurences, and max_count hold the number of times that character was
// found in the string.
@Michael,我看到你在发帖前回答了,我只是想用更详细的答案重复一遍。如果您自己编辑以添加更多解释,那么我将删除我的。我没有直接编辑你的,因为你发帖的时候我已经编辑到一半了。无论如何:
@Marco:
您可以创建一个包含 26 个计数器(初始化为 0)的临时数组。
每个计数器对应每个字母(即每个字母出现的次数)。例如 counter[0]
对应字母 'a' 的出现次数, counter[1]
对应字母 'b' 等...
然后遍历输入字符序列中的每个字符,并对每个字符执行:
a) 获取字符在counter
数组中的索引。
b) 将 counter["obtained index"]
增加 1。
要获取字符的索引,您可以执行以下操作:
a) 首先确保字符不是大写,即只允许 'a' 到 'z' 而不是 'A' 到 'Z'。如果不是,请转换它。
b) 从字符中减去字母'a'。这样 'a'-'a' 给出 0,'b'-'a' 给出 1,'c'-'a' 给出 2,等等...
我会用C语言演示,因为这是你在MIPS上的练习(我的意思是目标是学习MIPS汇编语言):
#include <stdio.h>
int main()
{
//Maximum length of string:
int stringMaxLength = 100;
//Create string in stack. Size of string is length+1 to
//allow the '[=10=]' character to mark the end of the string.
char str[stringMaxLength + 1];
//Read a string of maximum stringMaxLength characters:
puts("Enter string:");
scanf("%*s", stringMaxLength, str);
fflush(stdin);
//Create array of counters in stack:
int counter[26];
//Initialize the counters to 0:
int i;
for (i=0; i<26; ++i)
counter[i] = 0;
//Main counting loop:
for (i=0; str[i] != '[=10=]'; ++i)
{
char tmp = str[i]; //Storing of str[i] in tmp, to write tmp if needed,
//instead of writing str[i] itself. Optional operation in this particular case.
if (tmp >= 'A' && tmp <= 'Z') //If the current character is upper:
tmp = tmp + 32; //Convert the character to lower.
if (tmp >= 'a' && tmp <='z') //If the character is a lower letter:
{
//Obtain the index of the letter in the array:
int index = tmp - 'a';
//Increment its counter by 1:
counter[index] = counter[index] + 1;
}
//Else if the chacacter is not a lower letter by now, we ignore it,
//or we could inform the user, for example, or we could ignore the
//whole string itself as invalid..
}
//Now find the maximum occurences of a letter:
int indexOfMaxCount = 0;
int maxCount = counter[0];
for (i=1; i<26; ++i)
if (counter[i] > maxCount)
{
maxCount = counter[i];
indexOfMaxCount = i;
}
//Convert the indexOfMaxCount back to the character it corresponds to:
char maxChar = 'a' + indexOfMaxCount;
//Inform the user of the letter with maximum occurences:
printf("Maximum %d occurences for letter '%c'.\n", maxCount, maxChar);
return 0;
}
如果你不明白为什么我把大写字母加32转换成小写字母,那么请继续阅读:
每个字符在内存中对应一个整数值,当你对字符进行算术运算时,就相当于将它们变成编码中对应的数字table。
encoding 只是一个 table,它将这些字母与数字匹配。
例如 'a' 对应 ASCII encoding/decoding/table.
中的数字 97
例如 'b' 对应 ASCII encoding/decoding/table 中的数字 98。
所以'a'+1给出97+1=98就是字符'b'。它们都是内存中的数字,区别在于你如何表示(解码)它们。同样的table的编码,当然也用于解码。
示例:
printf("%c", 'a'); //Prints 'a'.
printf("%d", (int) 'a'); //Prints '97'.
printf("%c", (char) 97); //Prints 'a'.
printf("%d", 97); //Prints '97'.
printf("%d", (int) 'b'); //Prints '98'.
printf("%c", (char) (97 + 1)); //Prints 'b'.
printf("%c", (char) ( ((int) 'a') + 1 ) ); //Prints 'b'.
//Etc...
//All the casting in the above examples is just for demonstration,
//it would work without them also, in this case.