資料結構課設 詞頻統計
阿新 • • 發佈:2019-01-07
5-20 詞頻統計 (30分)
請編寫程式,對一段英文文字,統計其中所有不同單詞的個數,以及詞頻最大的前10%的單詞。
所謂“單詞”,是指由不超過80個單詞字元組成的連續字串,但長度超過15的單詞將只擷取保留前15個單詞字元。而合法的“單詞字元”為大小寫字母、數字和下劃線,其它字元均認為是單詞分隔符。
輸入格式:
輸入給出一段非空文字,最後以符號#
結尾。輸入保證存在至少10個不同的單詞。
輸出格式:
在第一行中輸出文字中所有不同單詞的個數。注意“單詞”不區分英文大小寫,例如“PAT”和“pat”被認為是同一個單詞。
隨後按照詞頻遞減的順序,按照詞頻:單詞
的格式輸出詞頻最大的前10%的單詞。若有並列,則按遞增字典序輸出。
輸入樣例:
This is a test.
The word "this" is the word with the highest frequency.
Longlonglonglongword should be cut off, so is considered as the same as longlonglonglonee. But this_8 is different than this, and this, and this...#
this line should be ignored.
輸出樣例:(注意:雖然單詞the
也出現了4次,但因為我們只要輸出前10%(即23個單詞中的前2個)單詞,而按照字母序,the
排第3位,所以不輸出。)
23
5:this
4:is
最後一個測試點過不了,聽說是哈利波特的節選,不太懂為什麼,求大神解答。
還有isdigit和isalpha函式居然用了就WA,不知是為什麼。。。
用了map,學會了利用vector對map根據value值排序。。然而卻沒大用到雜湊。。。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cctype> #include <vector> #include <map> using namespace std; bool cmp(pair<string, int> a, pair<string, int> b) { if(a.second != b.second) return a.second > b.second; else return a.first < b.first; } vector<pair<string, int> > v; map<string, int> m; int main(){ char str[100]; string word; map<string, int>::iterator it; int start = 0; char ch; while(ch = getchar()) { if(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9' || ch == '_') { if(ch >= 'A' && ch <= 'Z') ch = ch - 'A' + 'a'; str[start++] = ch; } else if(start > 0) { if(start >= 15) start = 15; str[start] = 0; start = 0; word = str; it = m.find(word); if(it != m.end()) { (it->second)++; } else { m[word] = 1; } } if(ch == '#') break; } for(it = m.begin(); it != m.end(); it++) { v.push_back(make_pair(it->first, it->second)); } sort(v.begin(), v.end(), cmp); vector<pair<string, int> > :: iterator itv; cout << v.size() << endl; int ans = v.size() / 10; for(itv = v.begin(); itv != v.begin() + ans; itv++) { cout << itv->second << ':' << itv->first << endl; } return 0; }