在字符串中计算单词出现次数

3
我将尝试计算字符串中单词的出现次数。对于字符串S,我需要显示每个单词以及该单词在字符串中出现的次数。
示例:
string = ";! one two, tree foor one two !:;"

结果:

one: 2
two: 2
tree: 1
foor: 1

这是我的代码,但它没有返回正确的计数:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int count_word(char * mot, char * text) {
  int n = 0;
  char *p;

  p = strstr(text, mot);

  while (p != NULL) {
    n++;
    p = strstr(p + 1, mot);
  }  

  return n;
}

void show_all_words(char * text) {
    char * p = strtok(text, " .,;-!?");

    while (p != NULL) {
      printf ("%s : %d\n", p, count_word(p, text));
      p = strtok(NULL, " .,;-!?");
    }
}

int main(char *argv[]) {

    char text[] = ";! one two, tree foor one two !:;";
    show_all_words(&text);

    return (EXIT_SUCCESS);
};

它正在返回:

one : 1
two : 0
tree : 0
foor : 0
one : 1
two : 0
: : 0

5
你是在问有关 C 还是 C++ 的问题吗?它们是不同的编程语言,标签不能混用。 - user229044
我已经修复了,并移除了C++标签,我现在是在问一个C语言的问题。 - Alex
2个回答

3
函数 strtok 会改变其参数。您可以通过复制字符串,在一个副本上调用 strtok,在另一个副本上调用 count_word 来解决问题。
此外,请注意不要重复输出相同单词的计数。
int count_word(char * mot, char * text, int offset) {
  int n = 0;
  char *p;

  p = strstr(text, mot);
  assert(p != NULL);
  if (p - text < offset)
      return -1; // if the word was found at an earlier offset, return an error code 

  while (p != NULL) {
    n++;
    p = strstr(p + 1, mot);
  }  

  return n;
}

void show_all_words(char * text) {
    char *text_rw = strdup(text); // make a read-write copy to use with strtok
    char * p = strtok(text_rw, " .,;-!?");

    while (p != NULL) {
      int offset = p - text; // offset of the word inside input text
      int count = count_word(p, text, offset);
      if (count != -1) // -1 is an error code that says "already looked at that word"
          printf ("%s : %d\n", p, count );
      p = strtok(NULL, " .,;-!?");
    }
    free(text_rw); // delete the copy
}

1

你应该改变方法。 可以使用一个数组来存储每个单词第一次出现的索引和出现次数。 在字符串中只需要遍历一次,但在辅助数组中需要遍历多次以检查当前单词是否已经计算过。

希望对你有用。


随着字符串的增大,为每个单词重新计数将会非常昂贵。您希望仅计算一次所有内容,然后进行报告。最好的方法是将所有标记放入数组中,然后按字母顺序对数组进行排序,然后进行计数。 - Rafael Baptista

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接