@Luxiaoye支持原創ios
做業連接:https://edu.cnblogs.com/campus/fzu/2019FZUSEZ/homework/9819算法
這次團隊編程中,我主要編寫第四模塊編程
-m 指定需統計的詞組長度
-n 指定須要輸出的詞頻排行的前n項windows四、統計文件中各詞組(單詞)的出現次數,最終只按照字典序輸出頻率最高的n個,n由輸入參數指定。app
- 該功能不影響單詞總數統計
- 同一詞組(單詞)不區分大小寫;例如,file、File和FILE是同一個單詞
- 頻率相同的單詞,優先輸出字典序靠前的單詞,例如,windows95,windows98和windows2000同時出現時,則先輸出windows2000
- 輸出的單詞統一爲小寫格式。
在通過隊友把文本內容處理以後,會變成以下格式。函數
格式:去掉不是規定單詞的單詞,單詞之間只用空格隔開,能夠多個空格,單詞的字母數大於等於4。編碼
標準樣例
文件輸入設計
Monday Tuesday Wednesday Thursday Friday
文件輸出code
<monday tuesday wednesday>: 1 <tuesday wednesday thursday>: 1
文件輸入orm
Iiii loove china china love iiii dsaaa bdsadsb AAAa aaaa aaaa aaaa aaaa AAAA Posoa jihoasj akkkp jihoasj akkkp
文件輸出
<aaaa aaaa aaaa>: 4 <akkkp jihoasj akkkp>: 1 <bdsadsb aaaa aaaa>: 1 <china china love>: 1 <china love iiii>: 1 <dsaaa bdsadsb aaaa>: 1 <iiii loove china>: 1 <jihoasj akkkp jihoasj>: 1 <loove china china>: 1 <posoa jihoasj akkkp>: 1
打開文件流
單行讀入
以r'(+?)個空格分割,就是多個空格分割。
處理分割後的數據分組
統計詞組 頻
根據傳參 m 和 n來輸出規定格式數據
寫規定格式數據流到文件
對字符串切割並根據規定長度聚合詞組函數算法,註釋有算法介紹
//對字符串切割並根據規定長度聚合詞組 vector<string> split(const string& str,const string& delim){ vector<string> res; vector<string> result; res.clear(); result.clear(); string ss; //以delim切割字符串到string向量res裏面 if("" == str) return res; char* strs = new char[str.length() + 1]; strcpy(strs,str.c_str()); char* d = new char[delim.length() + 1]; strcpy(d,delim.c_str()); char* p = strtok(strs,d); while(p){ string s = p; res.push_back(s); p = strtok(NULL,d); } if(res.size() >= m){//若是這一行的單詞個數小於規定的詞組長度,則不予加入詞頻的統計範圍 //今後行第0個單詞開始到 單詞數-m 個單詞 for(int kk = 0; kk <= res.size()-m; ++kk){ ss=""; //從第kk個單詞開始,後數m個,將這些單詞以規定格式聚合 for(int i = kk; i < kk + m -1; i++){ ss.append(res[i]) ; ss.append(" "); } //最後一個單詞後不聚合空格 ss.append(res[kk+m-1]); //將聚合後的放入向量result中 result.push_back(ss); } } return result; }
我重載了sort算法用於詞頻排序,由於map自己就是按字典序排列因此我只須要按詞頻排序
bool cmp(const pair<string, int>& a, const pair<string, int>& b) { return a.second > b.second; }
string line; //保存讀入的每一行 map<string,int> mp; while(getline(f,line))//讀入一行會自動把\n換行符去掉 { //轉小寫 transform(line.begin(),line.end(),line.begin(),::tolower); //空格分割後在all_str中保存單詞 vector<string> all_str = split(line," "); for(int i = 0; i < all_str.size(); ++i){ flag = 0;//定義flag標誌這次詞組是否出現 /* flag==0未出現 map中插入詞組及次數1 flag==1出現過 map.second的次數++ */ for(map<string,int>::iterator j = mp.begin(); j != mp.end(); ++j){ pair<string,int> it = *j; if(all_str[i] == it.first){ it.second++; mp.erase(all_str[i]); mp.insert(it); flag = 1; } } //若flag爲0 if(!flag){ pair<string,int> p_tmp(all_str[i], 1); mp.insert(p_tmp); } } } //將統計完成的詞組及詞頻map插入到總的vec中排序 vector< pair<string, int> > vec(mp.begin(), mp.end()); sort(vec.begin(), vec.end(), cmp);
//定義changdu爲要輸出的全部的詞組的長度 /* 若未指定m,則changdu取10與全部詞組總長度的最小值 若指定m,則changdu取m與全部詞組總長度的最小值 */ outfile.open(argv[outputpos],ios::app); if (m != 0) { if (vec.size() <= n) changdu = vec.size(); else changdu = n; for (int i = 0; i < changdu; ++i) { outfile << "<" << vec[i].first << ">: " << vec[i].second << endl; cout <<"<" << vec[i].first << ">: " << vec[i].second << endl; } } else { if (vec.size() <= 10) changdu = vec.size(); else changdu = 10; for (int i = 0; i < changdu; ++i) { outfile << "<" << vec[i].first << ">: " << vec[i].second << endl; cout << "<" << vec[i].first << ">: " << vec[i].second << endl; } } outfile.close();
更進一步掌握了vector和map的用法及結合使用