首页 > 解决方案 > 遍历字符数组以查找字母表中每个字母的出现

问题描述

到一定程度它会很好,就像 AG 会很好。但它会碰到像 I 或 H 这样的字母,并抛出一些疯狂的数字,比如 17 亿次出现,然后尝试在图中打印出那么多星号。我一直在努力解决这个问题并且无法弄清楚..这个for循环有什么问题?有问题的 for 循环在第 2 步中

#include <stdio.h>

#define MAXROWS 100
#define NUM_ALPHABETS 26

int main(){

        int count, i, j, k;

        char sentence[MAXROWS];
        char alphabets[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', '$
        int frequency[NUM_ALPHABETS];


// step 1:Write a function that reads a sentence from the keyboard (2 pts)
        printf("Please enter a sentence: \n");
        fgets(sentence, sizeof(sentence), stdin);

// step 2:Find out the frequency of the alphabets  in the sentence, ignore uppercase or lowercase in the sentence(4 pts)

        for(i = 0; sentence[i] != "\n"; i++) {
                for(j = 0; j < NUM_ALPHABETS; j++) {
                        if(tolower(sentence[i]) == tolower(alphabets[j])) {
                                frequency[j]++;
                        }
                }
        }


// step 3: Print the histogram as shown in the screenshot(4 pts)

        printf("%12s%12s%10s\n", "Alphabets", "Frequency", "Histogram");
        for(j = 0; j < NUM_ALPHABETS; j++) {
                printf("%12c%12d     ", alphabets[j], frequency[j]);
                for(k = 0; k < frequency[j]; k++) {
                        printf("*");
                }
                printf("\n");
        }

        return 0;
}

它应该打印出一个图表,并且它一直到某个点。但是一旦它碰到一些随机字母(每次都不是同一个字母),它就会计数大约 10 亿或 20 亿次(有时甚至是负数)

标签: carraysstringunix

解决方案


您是否依赖于将频率 [] 数组初始化为 0?

您也可以将步骤 2 编写为:

for(i = 0; sentence[i] != "\n"; i++) {
        if (isalpha(sentence[i]) {
                int index = tolower(sentence[i]) - 'a';
                frequency[index ]++;
        }
}

ps 注意你的单引号和双引号:

for(i = 0; sentence[i] != "\n"; i++)

这些应该是 '\n' 周围的单引号来表示一个字符。

正如其他人指出的那样,您需要初始化frequency. 有三种方法可以做到这一点:提供一个初始化器,编写一个将每个元素设置为零的循环,或调用memset(). 此代码执行所有三个操作:

int frequency[26] = { 0 };
for (int i = 0; i < 26; i++)
    frequency[i] = 0;
memset(frequency, 0, sizeof(frequency));

请注意,这frequency是错误的名称,因为它实际上包含每个字母的出现次数,而不是它们的频率。要获得频率,您必须除以读取的字符总数。MAXROWS也被错误命名,因为“行”是“行”的同义词;你可能想调用它MAXSENTENCELEN或类似的东西。

最后但同样重要的是,alphabets它也被错误命名,因为它只包含一个字母,但您实际上根本不需要它。只需检查字符是否为字母,如果是,则使用它与'A'or之间的差异'a'作为frequency. 对于加分,想办法避免检查和减法......(提示:ASCII中大写字母的数值和对应的小写字母仅相差一位)


推荐阅读