词频统计
1. 要求
实现一个控制台程序,给定一段英文字符串,统计其中各个英文单词(4字符以上含4字符)的出现频率。 附加要求:读入一段文本文件,统计该文本文件中单词的频率。
2. 定义
- 字母: A-Z, a-z.
- 字母数字: A-Z, a-z, 0-9.
- 分隔符: 非字母数字
- 单词:
- 包含有4个或4个以上的字母
- 单词由分隔符分开
- 如果一个字符串包含_非_字母数字,则不是单词
- 单词大小写不敏感,例如 “file”、“FILE”和“File”可以看作同一个单词
- 单词必须是字母开头,“file123”是单词,“123file”不是单词
3. 目标
开发工具:visual studio 2013
开发语言:c++
源程序
#include<iostream> #include<fstream> #include<cstring> using namespace std; struct Num{ int num = 1; char *s = NULL; }; Num word[99]; int Judge(char b[])//判断单词 { bool j1 = (strlen(b) >= 4); bool j2 = (b[0] >= 'a' && b[0] <= 'z'); if (!(j1&&j2)) return -1; else for (int ns = 1; b[ns] != '\0';) { if (!((b[ns] >= 'a' && b[ns] <= 'z') || (b[ns] >= '0' && b[ns] <= '9'))) return 1; else ns++; } } int Sta(char a[], int n) //判断该单词是否出现过 { if (n>0) for (int i = 0; i <n; i++) { if (!strcmp(a, word[i].s)) //出现 { word[i].num++; //+1 return 1; } } } int main() { char data[300]; ifstream file("e://data.txt"); if (!file){ cout << "Unable to open "; exit(1); } while (!file.eof()) { file.getline(data, 300); } file.close(); int x = 0; while (data[x] != '\0') //转小写 { if (data[x] >= 'A'&&data[x] <= 'Z') data[x] = data[x] + 32; x++; } const char *delim = " ,.'‘’"; //将非字母数字作为分隔符 char *p, *pNext = NULL; int n = 0, //计数器 n ,t 初始化 t = 0; p = strtok_s(data, delim, &pNext); //strtovk_s函数根据分隔符分隔字符串 while (p) { if (Judge(p) != 1) { if (Sta(p, n) != 1) { word[n].s = p; n++; } } p = strtok_s(NULL, delim, &pNext); } while (word[t].s) //输出统计结果 { cout << word[t].s << ":" << word[t].num << '\n'; t++; } return 0; }
数据测试
输入
Word is case insensitive, i.e. “file”, “FILE” and “File” are considered the same word.
结果
word: 2
case: 1
insensitive: 1
file: 3
considered: 1
same: 1
与给出输出一致
问题
在使用分隔函数strtok时我遇到了不少的麻烦,首先vs2013无此函数而应使用strtok_s函数,在百度相关教程之后完成了该函数的使用。