问题:
设计单词和字符计数器并显示特定字符的直方图。
直方图可以使用任何字符来表示特定字母的单个实例,例如X
,并且应该在该行的末尾打印该字母的实例数。仅打印输入句子中出现一个或多个字符的字符的结果。您的程序必须将同一个字母的小写和大写视为单独的字符。
下面是句子的直方图示例:i_Looooove__eps_II
Word total: 4
Character total: 18
Character total omitting underscore: 14
e: XX (2)
i: X (1)
o: XXXXX (5)
p: X (1)
s: X (1)
v: X (1)
I: XX (2)
L: X (1)
_: XXXX (4)
以下是我目前的情况:
void histogram(char array3[]){
char alphabet[25] = {0};
int count;
char *locate;
int i;
int j;
for(i=0; array3[i] != '\0'; i++){
array3[i] = tolower(array3[i]);
}
count = 0;
for(i = 0; i <= 25; i++){
locate = &array3[i];
while(locate = strchr(locate, 'a' + i)){
++count;
locate++;
}
alphabet[i] = count;
}
printf("\nThe number of occurrences of each letter is: \n");
for(i = 0; i <= 25;i++){
printf("%c:%3d\n", 'a' + i, alphabet[i]);
}
return;
}
有些东西没有按照我的预期运作:
直方图的输出是1而不是每个字符的出现次数。
答案 0 :(得分:1)
这不是一个好的开始:
locate = &array3[i];
您正在检查字母表中的每个i
字母(不区分大小写),并从输入字符串中的i
位置开始搜索该字母。这是错的。您还应该每次循环重置count
。
与传统方式相比,您的方法有点落后。您应该只计算遇到的那些字符,而不是搜索每个可能字符的整个字符串。这应该大致是你想要的:
int counts[256] = {0};
int num_words = 0; // Total number of words
int num_chars = 0; // Total number of characters (including underscores)
int num_underscores = 0; // Total number of underscores
int in_word = 0; // Are we currently inside a word?
for( int i = 0; str[i] != 0; i++ )
{
if( isalpha(str[i]) )
{
counts[str[i]]++;
num_chars++;
if( !in_word ) {
in_word = 1;
num_words++;
}
}
else if( str[i] == '_' )
{
counts[str[i]]++;
num_underscores++;
in_word = 0;
}
else {
// Unhandled character. Treat as word-break?
in_word = 0;
}
}
你可以从这里解决剩下的问题。
[edit] 我猜不是......
printf( "Word total: %d\n", num_words );
printf( "Character total: %d\n", num_chars );
printf( "Character total omitting underscore: %d\n", num_chars - num_underscores );
for( int i = 0; i < 256; i++ ) // Yes, this loop range is excessive...
{
if( counts[i] == 0 ) continue;
printf( "%c: ", (char)i );
for( int x = 0; x < counts[i]; x++ ) fputc('X', stdout);
printf( " (%d)\n", counts[i] );
}
如果你仍然对它感到困惑,这里提供的代码是为了显示纯粹的字符频率计数:
int counts[256] = {0};
for( int i = 0; str[i] != 0; i++ )
{
counts[str[i]]++;
}
请注意,每个可能的字符值都有一个数组位置。对于字符串中的每个字符,只需增加其计数即可。您只对counts['a']
,counts['b']
等感兴趣(对于大写和下划线也是如此)。但是如果您的输入表现良好,那么这很好,因为所有其他字符数将保持为零。
答案 1 :(得分:0)
这引起了问题
for(i = 0; i <= 25; i++)
我从0..25开始,即26个字符,但你的数组的尺寸只有25个字符:
char alphabet[25] = {0};
你的循环应该是
for(i = 0; i < 25; i++)