习题5.13 词频统计 (30point(s))
请编写程序,对一段英文文本,统计其中所有不同单词的个数,以及词频最大的前10%的单词。
所谓“单词”,是指由不超过80个单词字符组成的连续字符串,但长度超过15的单词将只截取保留前15个单词字符。而合法的“单词字符”为大小写字母、数字和下划线,其它字符均认为是单词分隔符。
Example:
#include <iostream>
#include <map>
#include <list>
#include <string>
#include <cstring>
using namespace std;
map<string, int> Read()
{
map<string, int> Freq{};
int top = 0;
while(1) {
char word[16];
char ch;
cin.get(ch);
if(isdigit(ch) || isalpha(ch) || ch == '_') {
if(top < 15) {
if('A' <= ch && ch <= 'Z') ch += 32;
word[top++] = ch;
}
} else if(top) {
word[top] = '\0';
top = 0;
Freq[word] += 1;
}
if(ch == '#') break;
}
return Freq;
}
int main()
{
map<string, int> Freq = Read();
list<pair<string, int>> Seq{};
for(auto &x : Freq) {
auto y = Seq.begin();
while(y != Seq.end()) {
if(y->second < x.second) break;
y++;
}
Seq.insert(y, x);
}
int cnt = Freq.size() / 10;
cout << Freq.size() << endl;
for(auto x = Seq.begin(); x != Seq.end(); x++) {
if(--cnt < 0) break;
cout << x->second << ':' << x->first << endl;
}
return 0;
}
思路:
使用 map 统计单词出现次数,然后按降序放入链表,最后打印前 N 个单词。