第四模塊

第四功能模塊的簡要設計

@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

須要實現的功能

  1. 打開文件流

  2. 單行讀入

  3. 以r'(+?)個空格分割,就是多個空格分割。

  4. 處理分割後的數據分組

  5. 統計詞組 頻

  6. 根據傳參 m 和 n來輸出規定格式數據

  7. 寫規定格式數據流到文件

    大體思路流程圖

文本詞組頻統計算法簡要介紹

切割聚合算法

對字符串切割並根據規定長度聚合詞組函數算法,註釋有算法介紹

//對字符串切割並根據規定長度聚合詞組
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的用法及結合使用

程序截圖

相關文章
相關標籤/搜索