1. 程式人生 > >軟工1816 · 作業(二)

軟工1816 · 作業(二)

count 命令行 自己 strings 統計 code 根據 每天 什麽

Github項目地址

Github

PSP表格

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 10 20
? Estimate ? 估計這個任務需要多少時間 10 20
Development 開發 380 495
? Analysis ? 需求分析 (包括學習新技術) 60 70
? Design Spec ? 生成設計文檔 30 10
? Design Review ? 設計復審 10 5
? Coding Standard ? 代碼規範 (為目前的開發制定合適的規範) 20 15
? Design ? 具體設計 10 5
? Coding ? 具體編碼 120 270
? Code Review ? 代碼復審 10 60
? Test ? 測試(自我測試,修改代碼,提交修改) 120 60
Reporting 報告 50 75
? Test Repor ? 測試報告 30 10
? Size Measurement ? 計算工作量 10 5
? Postmortem & Process Improvement Plan ? 事後總結, 並提出過程改進計劃 10 60
合計 440 590

解題思路

首先,拿到題目的時候,先分析了一下需求:

第一步、實現基本功能

  1. 以命令行參數傳入
  2. 統計文件的字符數
  3. 統計文件的單詞總數
  4. 統計文件的有效行數
  5. 統計文件中各單詞的出現次數,最終只輸出頻率最高的10個
  6. 按照字典序輸出到文件result.txt

第二步、接口封裝
把基本功能裏的:

  1. 統計字符數
  2. 統計單詞數
  3. 統計最多的10個單詞及其詞頻

這三個功能獨立出來,成為一個獨立的模塊,可以在幾個地方使用:

  1. 命令行測試程序使用
  2. 在單元測試框架下使用
  3. 與數據可視化部分結合使用

根據題目要求,很容易想到要使用C++文件的讀入讀寫操作來完成此次任務。所以先復習了一下文件的操作,還有上網查了一下詞頻的統計方法。

設計實現

根據基本功能,劃分以下六個函數:

  • isChinese 判斷是否是漢字
  • isWord
    判斷是否是單詞
  • isSign 判斷是否是分隔符
  • CountChar 統計字符個數
  • CountLine 統計有效行數
  • CountWord 統計單詞個數
  • CountTime 統計單詞頻率

其中統計字符個數和有效行數都是直接讀入文件,讀一個字符或一個換行符計數變量就加一。比較需要花功夫的是統計單詞的個數和單詞頻率,首先預處理txt裏的內容,把所有分隔符替換成空格,並且大寫全部轉換為小寫。之後將string轉換為stringstreamstringstream是以空格為界,先讀入每兩個空格之間的字符串再做漢字和單詞的判斷。至於單詞的排序,采用了mapvector數據結構相結合,先用map保存單詞和單詞頻率的關系,再用vector進行詞頻和字典序的排序。

代碼說明

while (getline(infile, s))
{
    for (int i = 0; i < s.size(); i++)
    {
        if (isChinese(s[i], s[i + 1]) == 1)//是漢字則跳過
        {
            i++;
        }
        else
        {
            if (isSign(s[i]) == 1)//是分隔符
            {
                s[i] = ‘ ‘;
            }
        }
    }
    str.append(s);
    str.append(1, ‘ ‘);
}
transform(str.begin(), str.end(), str.begin(), ::tolower);
stringstream ss(str);
map<string, int> strMap;  //保存的結果
string strTmp;
while (ss >> strTmp)
{
    if (isWord(strTmp) == 1)
    {
        map<string, int>::iterator it = strMap.find(strTmp);
        if (it == strMap.end())
        {
            strMap.insert(map<string, int>::value_type(strTmp, 1));
        }
        else
            strMap[strTmp]++;
    }
}
vector<pair<int, string> > vec;
MapSortOfValue(vec, strMap);
for (vector<pair<int, string> >::iterator it = vec.begin(); it != vec.end(); it++)
{
    n++;
    if (n <= 10)
    {
        vec2.push_back(make_pair(it->first, it->second));
    }
}
sort(vec.begin(), vec.end(), cmp);

心路歷程

首先很抱歉,由於這一周剛好新生入學,而我作為班導自然義不容辭需要帶領他們,新生教育周的活動安排得非常密集,所以我除了上課之外的空閑時間都在帶新生。每天基本上都是十一點才能回到宿舍有自己的時間,第二天早上六七點又要起床。很難有時間靜下心來寫程序。就連作業發表後我也是直到第二天才有時間看一眼。這次作業我沒有完成得很好,實現了基本功能後就已經沒剩什麽時間再完成擴展功能了,還有性能分析和單元測試,這是我之前沒有接觸過的,再學習新技能明顯已經來不及了。單元測試的Bug還沒改完。

軟工1816 · 作業(二)