0

我想计算一个句子的平均字长。

例如,给定输入abc def ghi,平均字长为3.0

该程序有效,但我想忽略单词之间的额外空格。因此,给定以下句子:

abc  def

(单词之间有两个空格),平均单词长度被计算为2.0而不是3.0

如何考虑单词之间的额外空格?这些将被忽略,这将给出上面示例中的平均字长3.0,而不是错误计算的2.0.

#include <stdio.h>
#include <conio.h>

int main()
{
char ch,temp;
float avg;
int space = 1,alphbt = 0,k = 0;

printf("Enter a sentence: ");

while((ch = getchar()) != '\n')
{
    temp = ch;

    if( ch != ' ')
    {
       alphbt++;
       k++;         // To ignore spaces before first word!!!
    }  
    else if(ch == ' ' && k != 0)
       space++;

}

if (temp == ' ')    //To ignore spaces after last word!!!
   printf("Average word lenth: %.1f",avg = (float) alphbt/(space-1));
else
   printf("Average word lenth: %.1f",avg = (float) alphbt/space);

getch();
}               
4

3 回答 3

4

计数逻辑是错误的。此代码似乎可以正确处理前导和尾随空格以及单词之间的多个空格等。请注意使用,int ch;以便代码可以准确地检查 EOF(getchar()返回一个int)。

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    int ch;
    int numWords = 0;
    int numLetters = 0;
    bool prevWasASpace = true; //spaces at beginning are ignored

    printf("Enter a sentence: ");
    while ((ch = getchar()) != EOF && ch != '\n')
    {
        if (ch == ' ')
            prevWasASpace = true;
        else
        {
            if (prevWasASpace)
                numWords++;
            prevWasASpace = false;
            numLetters++;
        }
    }

    if (numWords > 0)
    {
        double avg = numLetters / (float)(numWords);
        printf("Average word length: %.1f (C = %d, N = %d)\n", avg, numLetters, numWords);
    }
    else
        printf("You didn't enter any words\n");
    return 0;
}

各种示例运行,#用于指示Return被击中的位置。

Enter a sentence: A human in Algiers#
Average word length: 3.8 (C = 15, N = 4)

Enter a sentence: A human in Algiers  #
Average word length: 3.8 (C = 15, N = 4)

Enter a sentence:   A human  in   Algiers  #
Average word length: 3.8 (C = 15, N = 4)

Enter a sentence: #
You didn't enter any words

Enter a sentence: A human in AlgiersAverage word length: 3.8 (C = 15, N = 4)

Enter a sentence: You didn't enter any words

在最后一个示例中,我输入Control-D了两次(第一次将“阿尔及尔的人类”刷新到程序中,第二次输入 EOF),在最后一个示例中输入了一次。请注意,此代码将制表符计为“非空格”;你需要#include <ctype.h>if (isspace(ch))(或if (isblank(ch)))代替if (ch == ' ')更好地处理标签。


getchar()返回一个int

我很困惑你为什么使用int chand EOF

这个答案有几个部分。

  1. 使用的第一个原因int ch是该getchar()函数返回一个int. 它可以返回任何有效字符加上一个单独的值 EOF;因此,它的返回值不能是char任何类型的,因为它必须返回比 a 容纳的更多的值char。它实际上返回一个int.

  2. 为什么这有关系?假设 from 的值getchar()被分配给char ch。现在,对于大多数角色来说,大多数时候,它都可以正常工作。但是,会发生两种情况之一。如果 plainchar是有符号类型,则有效字符(通常为 ÿ、y-变音符号、0xFF、正式的 Unicode U+00FF、带分音符号的拉丁小写字母 Y)被误识别为 EOF。或者,如果 plainchar是无符号类型,那么您将永远不会检测到 EOF。

  3. 为什么检测 EOF 很重要?因为您的输入代码可能会在您不期望的情况下获得 EOF。如果您的循环是:

    int ch;
    
    while ((ch = getchar()) != '\n')
        ...
    

    并且输入达到EOF,程序将花费很长时间无所事事。该getchar()函数会重复返回EOF,而EOF不是'\n',所以循环会再试一次。始终检查输入函数中的错误条件,无论该函数是、 、getchar()还是scanf()它们的无数亲属。fread()read()

于 2013-06-16T06:27:20.920 回答
2

显然计算非空格字符很容易,你的问题是计算单词。为什么要像您一样将单词视为空格?或者更重要的是,什么定义了一个词?

IMO 单词被定义为从空格字符到非空格字符的过渡。所以,如果你能检测到这一点,你就可以知道你有多少个单词,你的问题就解决了。

我有一个实现,有很多可能的方法来实现它,我认为你想出一个不会有问题。我稍后可能会发布我的实现作为编辑。

*编辑:我的实现

#include <stdio.h>

int main()
{
    char ch;
    float avg;
    int words = 0;
    int letters = 0;
    int in_word = 0;

    printf("Enter a sentence: ");

    while((ch = getchar()) != '\n')
    {
        if(ch != ' ') {
            if (!in_word) {
                words++;
                in_word = 1;
            }
            letters++;
        }
        else {
            in_word = 0;
        }
    }

    printf("Average word lenth: %.1f",avg = (float) letters/words);
}
于 2013-06-15T23:39:16.970 回答
2

考虑以下输入:(连字符表示空格)

--Hello---World--

您当前忽略了初始空格和结束空格,但您计算了每个中间空格,即使它们彼此相邻。稍微改变你的程序,特别是'k',我们可以处理这种情况。

#include <stdio.h>
#include <conio.h>
#include <stdbool.h>
int main()
{
  char ch;
  float avg;
  int numWords = 0;
  int numLetters = 0;
  bool prevWasASpace = true; //spaces at beginning are ignored

  printf("Enter a sentence: ");

  while((ch = getchar()) != '\n')
  {
      if( ch != ' ')
      {
         prevWasASpace = false;
         numLetters++;
      }  
      else if(ch == ' ' && !prevWasASpace)
      {
         numWords++;
         prevWasASpace = true; //EDITED this line until after the if.
      }
  } 

  avg = numLetters / (float)(numWords);

  printf("Average word lenth: %.1f",avg);

  getch();
}          

您可能需要稍微修改前面的内容(尚未测试过)。

但是,仅根据单词之间的空格来计算句子中的单词可能不是您想要的一切。考虑以下句子:

约翰说:“拿起电话……现在!”

电视播音员刚刚提供了买一送一的优惠,同时说他们是 24/7 开放的。

他们每月花费的费用不会超过 100.99 美元(3.25 欧元)。

我立即用他/她的电话拨打 (555) 555-5555。

A(n) = A(n-1) + A(n-2) - 换句话说,序列:0,1,1,2,3,5, . . .

您将需要决定什么构成一个单词,这不是一个简单的问题(顺便说一句,你们所有人,没有一个例子包括所有种类的英语)。计算空格在英语中是一个很好的估计,但它不会让你一路走好。

查看有关文本分割的 Wikipedia 页面。这篇文章四次使用了“非平凡”这个短语。

于 2013-06-16T02:10:22.830 回答