【问题标题】:How to count total number of words without using string?如何在不使用字符串的情况下计算总单词数?
【发布时间】:2016-08-15 21:33:36
【问题描述】:

我实现了这个代码来获得否。字数。它适用于所有单个字符,即如果我输入 "q w r " 作为输入,它会给我 3 个单词,但是当我输入 "qwe ed df " 作为输入时,它显示 2。

#include<stdio.h>
int main()
{
    int c=getchar();

    int words=0;

    while(c!=EOF)
    {
        if(c==' ' || c=='\n')
        {
            c=getchar();
        }
        else if(c>='a' && c<='z')
        {  
            c=getchar();

            if(c==' ')
            {
                words=words+1;
                c=getchar();
            }
            else
            {
               c=getchar();
            }
        }
    }
    printf("%i\n",words);
}

【问题讨论】:

  • 正常的技术是使用while ((c = getchar()) != EOF)——顺便说一句,你会因为使用int c;而不是char c;而受到称赞——然后在循环中跟踪“我在说一句话”。如果您在一个单词中并且您阅读了一个非空格,那么您仍然在一个单词中。如果您在一个单词中并且您阅读了一个空格,那么您已经完成了一个单词(并且不再是一个单词)。如果你不在一个词中并且你得到一个非空格字符,那么你现在在一个词中;增加字计数器。如果你不在一个词中并且你得到一个空格,那么你仍然不在一个词中。 &lt;ctype.h&gt; 标头具有字符分类宏。
  • 读取在一个地方或前瞻和ungetc
  • 如果文件很大,考虑缓冲你的读取(例如char buf[1024] = ""; while (fgets (buf, 1024, stdin)) { char *p = buf; [your logic here]})。原因是,内存中的操作比一次一个字符的文件 I/O 快 数量级。 (您可以选择您的buf 大小以使其有意义。您将看到缓冲区小至 8 个字符的显着改进)

标签: c word-count


【解决方案1】:

诀窍是计算边界。

您的原始代码有一个错误...

        if(c==' ')
        {
            words=words+1;
            c=getchar();
        }

如果一对读取结果为'a' => 'z' 后跟' ',则代码仅计算字数。

诀窍是将循环简化为一次读取一个字符的循环。 (这确保不会出现奇怪的边界),以及一个状态机,它可以模拟您是在吃字还是吃空格。

enum Mode { word = 1, spaces = 2 };
int c=getchar();
enum Mode currentMode = spaces;
int words=0;

while(c!=EOF)
{
    if(c==' ' || c=='\n')
    {
        if( currentMode == word ) {
            words=words+1;
        }
        currentMode = spaces;
    }
    else if(c>='a' && c<='z')
    {  
        currentMode = word;
    }
c=getchar();
}
// count the last word...
if( currentMode == word ) {
    words=words+1;
}

代码现在将忽略任何非字母字符,既不是单词也不是空格。

编辑:修正了不正确的枚举用法

【讨论】:

  • 我认为您分配的模式状态不正确? (空格和单词切换)
  • 感谢@Daniel-Jour - 已修复
  • '这很有趣——你正在检测单词的结尾。如果您检测到单词的开头,则可以避免循环后的增量。您只需删除“if it is a space block”中的条件及其增量,并在您开始一个单词时增加(在“else if”块中)。我认为这会产生相同的答案。
【解决方案2】:

您的代码的问题是您对getchar 的分散调用隐藏了您所看到的错误。

您需要检查每个字符是否为空格以及每个字符是否为字母。

类似:

while ((c = getchar()) != EOF) {
     if (c == ' ' || c == '\n') {

     } else if (c >= 'a' && c <= 'z')

     } else {

    }
}

现在您只需要弄清楚这些分组中的逻辑即可。你有正确的逻辑(如果前一个字母是一个字符并且你得到一个空格然后增加这个单词,否则就继续)。但是您多次致电getchar 意味着您可能错过这种情况。

填补上面的空白,它应该可以工作。 (然后用大写字母进行测试!)。

【讨论】:

  • 再次在 else if 语句中我必须调用 getchar() 函数来查看是否在字母后输入了空格 ....那么它对前面的代码有什么影响?跨度>
  • @himanshujhamb:不,不要那样做,这就是你的问题所在。您可以跟踪前一个字母,或者有一个标志来标记您以前是否在一个单词中。
【解决方案3】:

您在 while 循环中的太多位置读取字符。这就是输出错误的原因。尝试使用这个循环:

while(c!=EOF)
{
    while(c == ' ' || c == '\n') //consume multiple spaces
    {
        c = getchar();
    }

    for( int i=0 ;c >= 'a' && c <= 'z'; i++) //consuming a word
    {
        if(i == 0) //increment word count once at the start of each word
        {
            words++;
        }

        c = getchar();
    }

}

【讨论】:

  • 是的,您可能会有人抱怨。但我认为这条线在现实范围内运作。
【解决方案4】:

你的代码有问题,字符串有

我认为偶数个字符

程序的逻辑并不完全正确,您必须在最后一个 else 中添加此条件:

 if(c==' ')
   {
     words=words+1;
     c=getchar();
   }

程序会是这样的:

  #include <stdio.h>

int main()
{
   int c=getchar();

    int words=0;

    while(c!=EOF)
    {
        if(c==' ' || c=='\n')
        {
            c=getchar();
        }
        else if(c>='a' && c<='z')
        {  
            c=getchar();
            if(c==' ')
            {
                words=words+1;
                c=getchar();
            }
            else
            {
               c=getchar();
               if(c==' ')
                {
                words=words+1;
                c=getchar();
                }
            }
        }
    }
    printf("%d\n",words);
    return 0;
}

因为当您输入两个字符的字符串并添加一个空格时,最后一个空格将被else 语句中的最后一个getchar 读取,该语句不会增加字数。

检查this results

我希望这会有所帮助!

【讨论】:

  • 你看到上面的结果了吗?这里又是Results.....
【解决方案5】:

每当一个字母跟在空格(空白)之后或者是第一个字母时,就增加您的字数。无需使用窄整数限制计数,文件可以很长。

// Useful is...() functions declared here.
#include <ctype.h>

unsigned long long words = 0;
int previous = ' ';
int ch;
while ((ch = getchar()) != EOF) {
  if (isspace(previous) && isalpha(ch)) words++;
  previous = ch;
}
 printf("%llu\n",words);

OP 可能想要调整代码以处理数字、标点符号等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多