1. 程式人生 > >軟件工程實踐第二次作業

軟件工程實踐第二次作業

txt 窗口 參數 ces cte urn 二次 英文 學習

WordCount

Github項目地址

PSP表格

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

解題思路描述:

      閱讀題目的過程中可以發現需要實現功能的主要有以下:
  • 讀取文件
  •    int main(int argc,const char* argv[])可從外部向程序傳遞參數。
      可以實現在命令窗口中(cmd)輸入:wordcount.exe intput.txt
      讀取文件是可根據需要按行讀取或者是按字符讀取等等;
      #includefstream>
      ofstream  //文件寫操作,從內存寫入存儲設備
      ifstream  //文件讀操作,存儲設備讀到內存中
      fstream   //讀寫操作,對打開的文件可進行讀寫操作
      再根據需要結合getchar()和getline()等等使用;
  • 統計文件的字符數
     字符要求:
    
     只需要統計Ascii碼,漢字不需考慮
    
     空格,水平制表符,換行符,均算字符
    思路:將文本掃描一遍,當遇到字符時計數加一。
  • 統計文件的單詞總數
       單詞要求:
      單詞:至少以4個英文字母開頭,跟上字母數字符號,單詞以分隔符分割,不區分大小寫。
      英文字母: A-Z,a-z
      字母數字符號:A-Z, a-z,0-9
      分割符:空格,非字母數字符號
      例:file123是一個單詞, 123file不是一個單詞。file,File和FILE是同一個單詞
    思路:利用正則表達式,寫好該單詞的正則式,循環一遍遇到匹配的計數加一
  • 統計文件的有效行數
      有效行數的要求:任何包含非空白字符的行,都需要統計。
    思路:按行讀取文件,對每一行進行循環,當遇到既不是空格也不是換行符,水平制表符等時計數加一
  • 統計文件中各單詞的出現次數
    要求:最終只輸出頻率最高的10個。頻率相同的單詞,優先輸出字典序靠前的單詞。

思路:先掃描一遍將大寫改成小寫,按查詢單詞數的方法找到匹配的單詞 ,放入map,vector,pair等容器相結合;再排序後輸出

  • 輸出的格式

    按照字典序輸出到文件result.txt
    characters: number

    words: number

    lines: number

    ...
    思路:用ofstream將結果寫入result.txt
    例如:

    ofstream out("result.txt",ios::in|ios::out);
    out.seekp(0, ios::end);
    out<<"xxxx:"<<xxxx<<endl;

設計實現過程:

在閱讀完題目之後,開始查找資料,看需要完成的功能該如何更好的實現。讀取文件有不同的方式,
選取一種方式;查找資料,學習使用正則式匹配單詞,正則式該怎麽書寫,怎麽寫循環進行匹配等;在統計
單詞頻率高的單詞用vector,map容器;將結果寫入result.txt文件,
c++編寫代碼,一個main調用  <字符統計函數> <有效行數統計函數>
<單詞統計函數> <統計文件中單詞出現次數>將代碼剝離開,按要實現的不同功能將代碼分成各個模塊;

改進的思路:

文件讀寫用ifstream和ofstream函數比較快;
一開始在匹配單詞想用雙指針自己寫匹配,自己書寫該代碼,工作量比較大,也比較繁瑣,後來發現可以用正則式來匹配,用現成的,來實現單詞的匹配更快一些,也比較簡便;利用sort()可以很方便的將10個出現頻率最高的單詞輸出;

代碼說明:

統計文件的單詞數
 #include"wordcount1.h"
 #include<string>
 #include<regex>
 #include<map>
 #include<fstream>
  int words_number(string txt)//統計文件的單詞總數
 {
     int count=0;
    map<string, int>m;
    string content;
    ifstream file(txt);
    regex wordtemplate("^[a-zA-Z]{4}[a-zA-Z0-9]*");//要求單詞的正則式
while (file >> content)
{

    const std::sregex_token_iterator  end;
    for (sregex_token_iterator wordIter(content.begin(), content.end(), wordtemplate); wordIter != end; wordIter++)
    {
        m[*wordIter]++;//統計每個單詞的個數;
    }
    
}
map<string, int>::const_iterator pp;

for (pp = m.begin(); pp != m.end(); pp++)
{
    count=count+pp->second;
}

file.clear();
file.seekg(0);
return count;


 }

統計出現頻率最高的10個單詞

 #include"frequent_words_count.h"
 #include <string>
 #include<map>
 #include<vector>
 #include<regex>
 #include<fstream>




 bool wordsort(pair<string, int>k1, pair<string, int> k2)
 {
   return k1.second > k2.second;
 }
 void frequent_words(string txt)//求出頻繁出現的十個單詞
 {
    unsigned int i;
    map<string, int>m;
    string content, add;
    ifstream file(txt);
    regex wordtemplate("^[a-zA-Z]{4}[a-zA-Z0-9]*");//要求單詞的正則式
    while (file >> content)
    {
        for (i = 0; i < content.length(); i++)//將大寫換成小寫
        {
            if (‘A‘ <= content[i] && content[i] <= ‘Z‘)
            {
                content[i] = content[i] + 32;
            }
        const std::sregex_token_iterator  end;
        for (sregex_token_iterator wordIter(content.begin(), content.end(), wordtemplate); wordIter != end; wordIter++)
        {
            m[*wordIter]++;//統計每個單詞的個數;
        }
    }
    file.clear();
    file.seekg(0);
    vector <pair<string, int>> v;
    for (map<string, int>::iterator iter = m.begin(); iter != m.end(); iter++)
    {
        v.push_back(pair<string, int>(iter->first, iter->second));
    }
    sort(v.begin(), v.end(), wordsort);
    int length = 10;
    if (v.size() < 10)
    {
        length = v.size();
    }
    vector<pair<string, int>>::iterator mm;
    ofstream out("result.txt", ios::in | ios::out);
    for (mm = v.begin(); mm != v.begin() + length; mm++)
    {
        out.seekp(0, ios::end);
        out << "<" << mm->first << ">" << mm->second << endl;
    }
    out.clear();

 }

小結

從這次實踐中,學習到在寫一個項目時,從開始時間規劃,需求分析,代碼設計,代碼書寫,測試數據,總結,知道了一個項目的完成是分成那些步驟,而不是像以前寫代碼,從一開始閱讀題目後,沒有設計就直接開始編寫代碼,以前的作業題目相對比較簡單,可以這樣草草的編寫,若如是開發一個大項目,沒有以上的步驟,只會加大自己的工作 量,也可能做不出結果;
代碼要學會很模塊,可以方便以後需要相同功能時可以直接使用。

軟件工程實踐第二次作業