如何提高 C 代码计算每行平均字数的效率?

How can I improve efficiency in my C code for calculating the average of words per line?

提问人:N4ti 提问时间:5/26/2023 最后编辑:N4ti 更新时间:5/26/2023 访问量:62

问:

enter image description here我正在尝试对数组中每行的单词进行平均。

我试图做一个程序来读取单词,直到输入EOF(通过+),然后它显示输入的单词数量(由空格或制表表符定义的单词)和每个句子的平均单词数(由OR定义的句子)。ctrlz.\n

这是我的代码,效果不佳。有谁知道我该怎么做才能至少使平均零件更有效率?它显示奇怪的数字。

#include <string.h>
#include <stdlib.h>
int main()
{
    char words[100]; int count=0, i, line=0, average;
    puts("enter words or CTRL + z");
    gets(words);
    do
    {
        for (i=0; i<strlen(words); i++)
        {
            if (words[i]== ' '|| words[i]=='\t' )
            {
                count = count + 1;
            }
            else
            {
                if (words[i]=='\n'||words[i]== '.')
                {
                    line = line + 1;
                    average = count/line;

                }
            }
        }
    }
    while (scanf("%99s",  words) != EOF);

    printf("total words = %d\n", count);
    printf("total sentences = %d\n", line);
    printf("average = %d\n", average);
    return 0;
}
数组 C 数组列表 EOF

评论

1赞 Harith 5/26/2023
您是否在至少 -O1 上进行了优化编译?1) 不要使用 .它已从 C 语言中删除。2)移出循环。3) 连续的字符串文字连接起来,对 进行一次调用。gets()strlen()printf()
0赞 Weather Vane 5/26/2023
对于初学者来说,转储已经过时,不再是标准 C 库的一部分。请阅读为什么 gets 函数如此危险,不应该使用?gets()
1赞 Harith 5/26/2023
当你还不能调试程序时,你为什么还要担心优化?它不起作用是无济于事的。给出的输入和接收的输出是什么?编译成功了吗?它怎么不起作用?
1赞 Harith 5/26/2023
@Weather 有一个之后。但你是对的,这是未初始化的。;char words[100];average
1赞 Weather Vane 5/26/2023
@Haris一个很好的例子,为什么不在一行上塞满两个语句。

答:

1赞 chux - Reinstate Monica 5/26/2023 #1

这是我的代码,效果不佳。

需要的更改

不要使用 gets()

用于读取一行fgets()

scanf(“%99s”, words) 无法读取

建议

while (fgets(words, sizeof words, stdin)) {
  ...
}

首先测试“\n”以计算行数

使用 isspace() 测试所有空格

考虑浮点平均值

只有在读取所有数据才需要。

double average = 1.0*count/line;

启用所有编译器警告


可能还有其他问题。

1赞 John Bollinger 5/26/2023 #2

永远不要,永远不要使用.你之所以可以访问它,只是因为 C 库的提供者更愿意避免破坏依赖它的遗留程序。Prefer 或 []。或者在某些情况下,可能同样好。gets()fgets()fscanffread

您将单词数计算为单词分隔符的数量。这通常会导致计数太少,因为它实际上忽略了第一个单词。在您的特定情况下,如果存在不附带单词分隔符的句子分隔符,它也会错过计数。我建议计算从非单词到单词的转换,其中非单词不仅包括单词分隔符,还包括句子分隔符。这也将解决如果一行中出现多个分隔符时单词计数错误的问题。

您的调用将忽略前导空格,并在之后找到的第一个空格处停止读取。这将完全搞砸多行输入的字数,你的句子也很重要(因为换行符是空格,因此将被忽略)。 会是一个更好的选择。scanf()fgets()

您不需要在每次遇到新行时都更新平均值,如果输入在行的中间结束,这将为您提供错误的结果。您可能应该等到读取整个输入后,再计算平均值。

每次测试时,您都会重新计算输入字符串的长度。除非你的编译器碰巧为你优化它,否则它的效率非常低。相反,要么预先计算长度,每行一次,要么测试是否已到达字符串终止符(例如,)。i < strlen(words)words[i] != '\0'

如果在句点后输入换行符,您的句子计数将是错误的(可以说)——它将计算两个句子,一个句子为零个单词。您可以考虑检测并纠正它,但也许评分员会认为您不应该这样做。

具有测试同一对象的特定值的所有条件的 / 树可能比语句效率低一点。IMO,也更容易阅读。ifelseswitchswitch

你说你想计算每的平均字数,但你实际上是在计算每句话的数量。你的规范说你要把换行符算作换句符,但据我所知,他们没有说相反的话,这不是一个自然的阅读。

你不需要你所展示的东西。如果你接通电话,也不会。但是,您确实需要 ,并且您不包括它。stdlib.hstring.hstrlen()stdio.h