简体   繁体   English

C程序中的字长频率

[英]Word length frequency in C Program

I am trying to write a simple C program to output the length of words and output their frequencies. 我正在尝试编写一个简单的C程序来输出单词的长度并输出其频率。 For example, if the user inputs "hey" my program would output Length of word: 3 Occurrences 1, and so on with a larger string inputted. 例如,如果用户输入“嘿”,我的程序将输出字长:3次出现1,依此类推,并输入了较大的字符串。 I just cannot seem to loop it properly. 我似乎无法正确地循环它。 I thought of setting both counters when a delimiter is seen to count both the length of the word at the time and its occurrence but I have not found a way for it to work. 我曾想过要在看到分隔符时同时计算单词的长度和出现的次数时设置两个计数器,但是我还没有找到一种可行的方法。 How can I fix my loop? 如何修复循环? My code is below. 我的代码如下。 I'd appreciate any help. 我将不胜感激。 I should include my program only runs correctly for one word inputted but not a whole sentence or multiple sentences. 我应该让我的程序仅针对输入的一个单词正确运行,而不是整个句子或多个句子正确运行。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
const char delim[] = ", . - !*()&^%$#@<> ? []{}\\ / \"";
const int n_delim = 31;
#define SIZE 1000

int is_delim(int c);
int main(){
    char string[SIZE];
    int wordlength = 0, wl[SIZE];
    int word = 0, i;


    printf("Enter your input string:");
    fgets(string, SIZE, stdin);
    string[strlen(string) - 1] = '\0';

printf("Word Length\tCount\n");
    int seen = 0;
    int l;
    for (i = 0; i < strlen(string); i++){
        if (is_delim(string[i])){
            wl[word++] = wordlength;
            l = wordlength;
            seen++;
            printf("%d\t\t%d\n", l, seen);
            wordlength = 0;
        }
        wordlength++;

    }
    return 0;
}

int is_delim(int c){
    register int i;
    for (i = 0; i < n_delim; i++)
        if (c == delim[i]) return 1;
    return 0;
}

The trick is that wl[n] holds the count of words of length n. 诀窍是wl [n]保留长度为n的单词计数。 Also, you don't need to keep calling strlen() on every iteration, just check for the zero byte at the end. 另外,您不需要每次迭代都继续调用strlen(),只需检查最后的零字节即可。 The optimizer will do this for you, if you enable it. 如果启用它,优化器将为您执行此操作。 The odd-looking for(;1;) is so that the loop counts the final word, which is terminated by the zero byte. 奇数的for(; 1;)使得循环对最后一个字计数,该字以零字节结尾。

memset(wl,0,sizeof(wl));
for(wordStart=maxLength=i=0;1;i++) {
  if(is_delim(string[i]) || string[i]==0) {
    int wordLength= i-wordStart;
    if(wordLength>0)
      wl[wordLength]++;
    if(wordLength>maxLength)
      maxLength= wordLength;
    wordStart= i+1;
  }
  if(string[i]==0)
    break;
}

for(i=1;i<=maxLength;i++) {
  if(wl[i]>0) {
    printf("%d words of length %d.\n",wl[i],i);
  }
}

You really should use strtok for this. 您确实应该为此使用strtok Right now, you never compare the last string with the current one so you can't tell them apart. 现在,您永远不会将最后一个字符串与当前字符串进行比较,因此无法区分它们。 You can use strcmp for this. 您可以为此使用strcmp Finally instead of manually testing the length of the string you should use strlen . 最后,应该手动使用strlen而不是手动测试字符串的长度。 Here is how your loop could look like 这是循环的样子

int seen = 0;

pch = strtok(string, delim);
last = pch;
while(pch != NULL) {
  if(strcmp(last, pch) != 0) {
    printf("%s:\t%d\t\t%d\n", last, (int)strlen(last), seen);
    seen = 1;
  }else {
    seen++;
  }
  last = pch;
  pch = strtok(NULL, delim);
}
printf("%s:\t%d\t\t%d\n", last, (int)strlen(last), seen);

Note, you should set the variable seen to 0 before the loop. 请注意,您应该设置变量seen循环之前为0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM