軟工實踐第二次作業
GitHub
PSP表格
| PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
|---|---|---|---|
| Planning | 計劃 | 25 | 35 |
| ? Estimate | ? 估計這個任務需要多少時間 | 1015 | 980 |
| Development | 開發 | 300 | 320 |
| ? Analysis | ? 需求分析 (包括學習新技術) | 180 | 200 |
| ? Design Spec | ? 生成設計文檔 | 10 | 10 |
| ? Design Review | ? 設計復審 | 20 | 10 |
| ? Coding Standard | ? 代碼規范 (為目前的開發制定合適的規范) | 20 | 10 |
| ? Design | ? 具體設計 | 20 | 20 |
| ? Coding | ? 具體編碼 | 200 | 180 |
| ? Code Review | ? 代碼復審 | 30 | 15 |
| ? Test | ? 測試(自我測試,修改代碼,提交修改) | 120 | 100 |
| Reporting | 報告 | 45 | 25 |
| ? Test Repor | ? 測試報告 | 10 | 10 |
| ? Size Measurement | ? 計算工作量 | 20 | 25 |
| ? Postmortem & Process Improvement Plan 11 | ? 事后總結, 并提出過程改進計劃 | 15 | 20 |
| 合計 | 1015 | 980 |
解題思路
-
因為對java不是很了解,所以我選擇用“C++”來解決這個作業。因此在拿到作業后,我先去查找了有關“C++”如何讀取和輸出文件,以及一些相關的頭文件。
-
題目要求的是統計文件內容的字符數、內容的有效行數、以及單詞出現頻率和匹配的單詞個數。
-
輸出格式為:
characters: number words: number lines: number <word1>: number <word2>: number ...
在進行統計文件內容字符數時,我想要逐個字符讀入這樣子方便統計,而在進行統計文件有效行數時,則希望能夠按行讀取文件,再判斷該行是否為有效行數。而在詞頻統計和統計單詞個數上遇到了點問題,感覺這個題很難啊T T,一開始還是沒什么思路。后來通過不斷查閱資料,以及和同學之間進行交流,嘗試使用正則式,通過正則式來篩選題目要求的單詞。
設計實現過程
-
首先明確,將要執行的任務分成三個部分:一個負責統計文件的有效字符個數,一個負責統計文件的有效行數,一個負責詞頻統計和統計單詞個數,最后將結果一起輸出文本。
-
在寫函數前首先是要學習如何讀取文件。
-
在查找了相關的資料后,加入了頭文件
,在統計字符個數的時候采用逐個字符讀入的方法(包括空格和回車):infile >> noskipws; -
在統計有效行數的時候,讀取文件使用了get()函數,采取按行讀入,并且循環查找行中是否存在除了空格、換行、回車外的字符,如果存在就跳出循環并且行數+1.
-
接下來就是匹配查找符合條件的單詞,并且統計單詞出現的頻率。在詞頻平統計中套用了正則式的模板,逐個查找,并且實現將大寫字母轉換成小寫字母的功能。最后使用了map去統計出現頻率最高的十個單詞。
代碼說明和測試
-
統計文件內有效字符的個數
int charcount(string filename)
{int count1 = 0;
ifstream infile;
infile.open(filename.data()); //將文件流對象與文件連接起來
assert(infile.is_open()); //若失敗,則輸出錯誤消息,并終止程序運行char c;
infile >> noskipws;//逐個字符讀入(包括空格和回車)
while (infile >> c)
{if (c >= 0 && c <= 255)
{
count1++;
}
}infile.close();//關閉文件輸入流
return count1;
} -
統計單詞的個數以及詞頻統計同時寫入文件
bool findword(pair<string, int> elem1, pair<string, int> elem2)
{
return elem1.second > elem2.second;
}
void frequency(string filename)
{
ofstream output("1.txt", ios::app);//調用ofstream函數創建輸出文件:1.txt; ios::app讓后來寫的內容接在上一次寫的結尾string s;
map<string, int> find;
regex WordPatternreg("[1]{4}[a-z0-9]");//我們要匹配的單詞的正則式
ifstream ifs(filename);//強制讀取文件內容
while (ifs >> s)
{
int l = s.length();//
for (int i = 0; i < l; i++)
{
if (s[i] >= 65 && s[i] <= 90)
{
s[i] = s[i] + 32;
}
}//將大寫轉換成小寫
const std::sregex_token_iterator end;
for (sregex_token_iterator wordIter(s.begin(), s.end(), WordPatternreg); wordIter != end; wordIter++)
{//在一行文本中逐個找出單詞
//cout<<wordIter<<endl;//每個單詞
find[*wordIter]++;//單詞計數
}
}
ifs.clear();
ifs.seekg(0);vector<pair<string, int>> ci;
for (map<string, int>::iterator iter = find.begin(); iter != find.end(); iter++)
{
ci.push_back(pair<string, int>(iter->first, iter->second));
}
sort(ci.begin(), ci.end(), findword);
int size = 10;int count3 = ci.size();//統計數組里單詞的個數
if (output.is_open())
{output << "word:" << count3 << endl;
if (ci.size() < 10)
{
size = ci.size();
}vector<pair<string, int>>::iterator vit;
for (vit = ci.begin(); vit != ci.begin() + size; vit++)
{
output << "<" << vit->first << ">:" << " " << vit->second << endl;
}
}
output.close();
}
部分測試結果


心得體會
這是第二次實踐作業了。說實話,我覺得第二次的實踐作業對我來說真的是太難了T T。但是人只有在挫折中才會慢慢成長起來。通過這次實驗其實學了很多。以前都知識簡簡單單敲那種給一個問題寫一個程序的代碼。而這次除了要編寫代碼之外,還得學會如何用C++讀取和輸出文件,如何將代碼進行接口封裝,當然最重要的是要學習如何百度獲取自己所需要的知識。百度真的是萬能啊...感慨一下...以前真的很少使用百度學習一些其實課上學不到的東西。比如這次用到的頭文件,基本上是上課沒有怎么提到過的。真的學會百度非常重要,第一次體會到能夠從網上學知識并且能夠馬上應用到實際。同時真的深切感受到自己的知識點真是太少了,,說實話這次的實踐真的是做得挺吃力得...因為vs有點問題...代碼之后還會繼續修改...說實話這次的實踐真的是做得挺吃力得...艱難地成長...
a-z ??
浙公網安備 33010602011771號