【问题标题】:how to check how many times 'a' shows?如何检查“a”显示了多少次?
【发布时间】:2017-02-12 01:24:12
【问题描述】:
int main (void)
{
    char input[99999];

    int  times=0;
    int  words=0,a=0;

    while ((input[a]=getchar()) != EOF) // get input
        {
        a++;
        }
    for (int n=0;n<=a;n++)
    {
        if(input[n]<='z' && input[n]>='a' ){words++;}       
    }
    float freq=times/words;

    for(char letter ='a'; letter<='z'; letter++)
    {
        for (int n=0;n<=a;n++)
        {
            if(input[n]==letter){times++;}
        }
        printf( "%c %.4f\n", letter, freq); 
    }
}

我得到了结果:

asdf a
a 0.0000
b 0.0000
c 0.0000
d 0.0000
e 0.0000
f 0.0000
g 0.0000
h 0.0000
i 0.0000
j 0.0000
k 0.0000
l 0.0000
m 0.0000
n 0.0000
o 0.0000
p 0.0000
q 0.0000
r 0.0000
s 0.0000
t 0.0000
u 0.0000
v 0.0000
w 0.0000
x 0.0000
y 0.0000
z 0.0000

【问题讨论】:

  • 编写一个程序,计算文本中字母出现的频率。
  • 我不知道为什么 |if(input[n]==letter){times++;}|不工作

标签: arrays for-loop char compare


【解决方案1】:

您的代码中有三个大问题:

  1. 你在错误的地方计算freq。当 times 仍为 0 时,您使用 times/words。(自初始化以来,您尚未为其分配任何内容。)这需要在 for 循环的末尾进行。
  2. 您没有在for 循环的每次迭代中将times 设置回0,因此它是累积的。 (如果你有 3 个as 和 4 个bs,timesb 迭代之后将是 7。)
  3. 您正在使用整数除法,但您需要先将分子转换为浮点数:(float)times / words

我做了一些其他的清理工作,比如将 words 重命名为 letters 和将 a 重命名为 length,因为这些似乎更好地反映了这些变量在做什么。下面是一个完整的工作版本:

#include <stdio.h>

int main (void)
{
    char input[99999];

    int letters = 0, length = 0;

    while ((input[length++] = getchar()) != EOF);

    for (int n = 0; n < length; n++)
    {
        if (input[n] >= 'a' && input[n] <= 'z')
        {
            letters++;
        }       
    }

    for(char letter = 'a'; letter <= 'z'; letter++)
    {
        int times = 0;
        for (int n = 0; n < length; n++)
        {
            if (input[n] == letter)
            {
                times++;
            }
        }

        float freq = (float)times / letters;
        printf("%c %.4f\n", letter, freq);
    }
}

字符串“hello”通过管道传输到程序时的示例输出:

a 0.0000
b 0.0000
c 0.0000
d 0.0000
e 0.2000
f 0.0000
g 0.0000
h 0.2000
i 0.0000
j 0.0000
k 0.0000
l 0.4000
m 0.0000
n 0.0000
o 0.2000
p 0.0000
q 0.0000
r 0.0000
s 0.0000
t 0.0000
u 0.0000
v 0.0000
w 0.0000
x 0.0000
y 0.0000
z 0.0000

更新

请注意,您的解决方案效率很低。您需要读取输入的每个字符 26 次(每个字母一次)。

您可以改为使用包含 26 个计数的数组,并通过输入一次性更新它们。这是该解决方案的一种可能性:

包括

包括

int main (void)
{
    char input[99999];
    int counts[26] = { 0 };
    int length = 0, total = 0;

    while ((input[length++] = getchar()) != EOF);

    for (int i = 0; i < length; i++) {
        char c = tolower(input[i]);
        if (c >= 'a' && c <= 'z') {
            counts[c - 'a'] += 1;
            total += 1;
        }
    }

    for (int i = 0; i < 26; i++) {
        if (counts[i] > 0) {
            printf("%c %.4f\n", 'a' + i, (float)counts[i] / total);
        }
    }
}

【讨论】:

  • wt 如果同时计算'A'和'a'一次'a'?这个方法还能用吗?
  • 然后计数[input[i]-'A'] ?
  • @BEIXIN 没错。要么先转换为小写,要么检查它在哪个范围内并减去正确的数量。
  • @BEIXIN 我已经更新了我上一个代码 sn-p 以将每个字符转换为小写。
【解决方案2】:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (void)
{
    char input[99999];  
    int a=0;
    float  words=0.0,times=0;

    while ((input[a]=getchar()) != EOF) // get input
        {
        a++;
        }
    for (int n=0;n<=a;n++)
    {
        if(input[n]<='z' && input[n]>='a' ){words++;}       
    }
    float freq=0;

    for(char letter ='a'; letter<='z'; letter++)
    {
        for (int n=0;n<=a;n++)
        {
            if(input[n]==letter){times++;}
        }
        freq=times/words;
        if(freq!=0){printf( "%c %.4f\n", letter, freq); }
        times=0;
    }

}

【讨论】:

    猜你喜欢
    • 2021-10-05
    • 2021-08-11
    • 2011-03-31
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-19
    • 1970-01-01
    相关资源
    最近更新 更多