字数统计程序 - stdin

Word count program - stdin

下面question,

Write a program to read English text to end-of-data (type control-D to indicate end of data at a terminal, see below for detecting it), and print a count of word lengths, i.e. the total number of words of length 1 which occurred, the number of length 2, and so on.

Define a word to be a sequence of alphabetic characters. You should allow for word lengths up to 25 letters.

Typical output should be like this:

        length 1 : 10 occurrences
        length 2 : 19 occurrences
  length 3 : 127 occurrences
     length 4 : 0 occurrences
        length 5 : 18 occurrences
        ....

To read characters to end of data see above question.


这是我的工作解决方案,

#include<stdio.h>
int main(void){
  char ch;
  short wordCount[20] = {0};
  int count = 0;
  while(ch = getchar(), ch >= 0){
    if(ch == ' ' || ch == ',' || ch == ';'|| ch == ':'|| ch == '.'|| ch == '/'){
      wordCount[count]++;
      count=0;
    }else{
      count++;
    }
  }
  wordCount[count]++; // Incrementing here looks weird to me

  for(short i=1; i< sizeof(wordCount)/sizeof(short); i++){
    printf("\nlength %d : %d occurences",i, wordCount[i]);
  }
}

问题:

1)

从代码优雅的角度来看,我可以避免在 while 循环之外递增 (++) wordCount 吗?

2)

我能否使 wordCount 数组大小根据单词大小而不是恒定大小 20 更加动态?

注意:了解了 struct 但我还没有学习像 Linkedlist

这样的动态结构

至 1): 也许从一个分隔符扫描到下一个分隔符,直到递增 wordCount。也使 EOF 成为定界符。

至 2) 您可以扫描文件两次,然后决定需要多少内存。或者在需要更多内存时动态 realloc 。例如,这是 std::array class 在内部执行的操作。

另外你应该想想如果有两个 字符一个接着一个会发生什么。现在你会把它算作一个词。

对于动态分配,您可以从 space for 20 shorts 开始(尽管问题陈述似乎要求您允许最多 25 个字符的单词):

short maxWord = 20;
short *wordCount = malloc(sizeof(*wordCount) * maxWord);

然后,当您递增 count 时,如果当前单词的长度超过动态数组中可以计算的长度,您可以分配更多 space:

} else {
    count++;
    if (count >= maxWord) {
        maxWord++;
        wordCount = realloc(sizeof(*wordCount) * maxWord);
    }
}

完成后别忘了free(wordCount)

由于不需要计算零长度的单词,可以考虑修改代码,wordCount[0]存储长度为1的单词数,依此类推。