軟工1816 · 做業(二)

Github項目地址

Githubgit

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

解題思路

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

第一步、實現基本功能數據結構

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

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

  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)); //插入map
        }
        else
            strMap[strTmp]++; //詞頻+1
    }
}
vector<pair<int, string> > vec;
MapSortOfValue(vec, strMap); //利用vec排序
for (vector<pair<int, string> >::iterator it = vec.begin(); it != vec.end(); it++)
{
    n++;
    if (n <= 10) //選出詞頻最高的10個單詞
    {
        vec2.push_back(make_pair(it->first, it->second));
    }
}
sort(vec.begin(), vec.end(), cmp); //最後再以字典序排序

心路歷程

首先很抱歉,因爲這一週恰好新生入學,而我做爲班導天然責無旁貸須要帶領他們,新生教育周的活動安排得很是密集,因此我除了上課以外的空閒時間都在帶新生。天天基本上都是十一點才能回到宿舍有本身的時間,次日早上六七點又要起牀。很難有時間靜下心來寫程序。就連做業發表後我也是直到次日纔有時間看一眼。此次做業我沒有完成得很好,實現了基本功能後就已經沒剩什麼時間再完成擴展功能了,還有性能分析和單元測試,這是我以前沒有接觸過的,再學習新技能明顯已經來不及了。單元測試的Bug還沒改完,最後在性能分析的時候,VS崩潰了,連運行都運行不了,致使只能先把已作完的部分提交。
因此,建議給本身的deadline能夠比任務的實際deadline早那麼一天,好應對一些突發情況。
再接再礪吧。下一次做業必定不這麼趕了。學習

相關文章
相關標籤/搜索