做業連接: | https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/homework/2882 |
GIT倉庫地址: | https://github.com/wangli20173106/WordCount |
結對人員: | 201731062318王力;201731062315餘希倫 |
PSP2.1git |
Personal Software Process Stagesgithub |
預估耗時(分鐘)正則表達式 |
實際耗時(分鐘)編程 |
Planning函數 |
計劃佈局 |
30性能 |
20單元測試 |
· Estimate學習 |
· 估計這個任務須要多少時間測試 |
30 |
20 |
Development |
開發 |
440 |
370 |
· Analysis |
· 需求分析 (包括學習新技術) |
20 |
20 |
· Design Spec |
· 生成設計文檔 |
30 |
40 |
· Design Review |
· 設計複審 (和同事審覈設計文檔) |
60 |
40 |
· Coding Standard |
· 代碼規範 (爲目前的開發制定合適的規範) |
60 |
40 |
· Design |
· 具體設計 |
30 |
30 |
· Coding |
· 具體編碼 |
180 |
150 |
· Code Review |
· 代碼複審 |
30 |
30 |
· Test |
· 測試(自我測試,修改代碼,提交修改) |
30 |
20 |
Reporting |
報告 |
90 |
80 |
· Test Report |
· 測試報告 |
30 |
30 |
· Size Measurement |
· 計算工做量 |
30 |
20 |
· Postmortem & Process Improvement Plan |
· 過後總結, 並提出過程改進計劃 |
30 |
30 |
|
合計 |
560 |
470 |
小結:看到題目以後,仔細審題並看來做業要求,評分指標,明顯感受此次做業難度更大,咱們首先兩我的商量制定PSP,使得整個
項目過程清晰明瞭,能夠更好的把控項目進度和花費時間,而後從新複習了一遍《面向對象編程C#》這本書,溫習了C#,而後閱讀了
助教小姐姐的相似博客,就開始設計結構,明確分工,提升了開發效率和軟件質量。
2.1:代碼規範
1.程序整體邏輯結構清晰,註釋簡潔清楚,十分方便別人閱讀並理解代碼;
2.對C#的一些函數比較熟悉;
3.運用了正則表達式處理單詞識別的問題;
4.代碼總體佈局風格統一,比較規範;
5.主函數不宜寫太長
6.能夠把實現不一樣功能的部分代碼抽取出來用函數實現。
2.2:互審過程及問題
提早制定了代碼規範,而且設計了程序運行的結構,使得寫出來的代碼格式清晰,各部分函數分工明確,
讓人很容易讀懂代碼的內容,瞭解程序的運行過程。餘希倫是領航員,我是駕駛員,參照《軟件工程原理》
中結對編程模式,共同開發。
程序結構設計
輸入類設計
難點:單詞計數類設計
輸出類:
Main()方法
Main()方法中調用TestMethod()方法,接着由TestMethod()依次調用program.DataInput();//輸入program.FileRead(path);//文件讀取
program.MainCount();//計數program.Output();//輸出program.FileSave();
public void TestMethod() { program.DataInput();//輸入 program.FileRead(path);//文件讀取 program.MainCount();//計數 program.Output();//輸出 program.FileSave();//生成文本文件 } public void TestMethod(string l_path, string S_path, int num, int outNum) { path = l_path; number = num; outPutNum = outNum; s_path = S_path; program.FileRead(path); program.MainCount(); program.Output(); program.FileSave(); }
DataInput()
DataInput()方法寫的方法和代碼執行過程相對應,同時易於理解輸入
void DataInput() { Console.WriteLine("輸入讀取文檔路徑:"); path = Console.ReadLine(); Console.WriteLine("輸入想要輸出的詞組長度:"); number = int.Parse(Console.ReadLine()); Console.WriteLine("輸出單詞數量:"); outPutNum = int.Parse(Console.ReadLine()); Console.WriteLine("輸出存儲路徑:"); s_path = Console.ReadLine();
文件讀寫代碼
void FileRead(string path) { StreamReader sr = new StreamReader(path, Encoding.Default); string line; while ((line = sr.ReadLine()) != null) { Lines.Add(line); } }
核心代碼:MainCount()
這個方法用於判斷單詞字符,應該是最難的部分,爲了方便理解,代碼中有詳細註釋。
void MainCount() { int wordJudge = 0;//單詞長度標記 int MutiWords = 0;//判斷目前是否爲詞組記錄狀態的標誌變量 int MutiWordsJudge = 0;//詞組長度標記 bool isWord = true; string _word = ""; foreach (var str in Lines) { int lineJudge = 0; foreach (var word in str) { //判斷當前檢測字符是否爲空 if (word != ' ') { lineJudge++; characters++; //判斷當前是否爲單詞檢測狀態,判斷當前檢測字符是否爲字母 if ((isWord == true) && (((word >= 65) && (word <= 90)) || ((word >= 97) && (word <= 122))))//判斷是否爲字母內容 { wordJudge++; _word = _word + word; } else { //切換至非單詞狀態 if (wordJudge == 0) { isWord = false; MutiWords++; } else { //判斷當前是否爲單詞數字後綴 if ((wordJudge >= 4) && ((word >= 48) && (word <= 57))) { _word = _word + word; } else { //判斷是否已經構成單詞 if (wordJudge >= 4) { WordAdd(_word); wordJudge = 0; _word = ""; } //結束當前判斷週期,從新切換至單詞檢測狀態 else { wordJudge = 0; _word = ""; isWord = true; MutiWords = 0; } } } } } else { MutiWordsJudge++; //檢測到空字符時結束當前判斷週期,開啓新週期 isWord = true; MutiWords = 0; //判斷當前檢測結果是否構成單詞 if (wordJudge >= 4) { WordAdd(_word); wordJudge = 0; _word = ""; } else { MutiWords++; wordJudge = 0; _word = ""; MutiWordsJudge = 0; } if ((MutiWords == 0) && (MutiWordsJudge == number)) { MutiWordsAdd(); MutiWordsJudge = 0; } } } //在行末判斷是否已構成單詞 if (wordJudge >= 4) { WordAdd(_word); wordJudge = 0; _word = ""; if ((MutiWords == 0) && (MutiWordsJudge == number - 1)) { MutiWordsAdd(); MutiWordsJudge = 0; } } //判斷當前行是否爲有效行 if (lineJudge != 0) { lines++; } } }
Output()
void Output() { List<string> words = program.WordSort(); Console.WriteLine("字符:" + program.characters); SaveStrs.Add("字符:" + program.characters); Console.WriteLine("單詞:" + program.Words.Count); SaveStrs.Add("單詞: " + program.Words.Count); Console.WriteLine("行:" + program.lines); SaveStrs.Add("行:" + program.lines); int i = 0; //輸出高頻單詞 if (Words.Count < outPutNum) { for (; i < Words.Count; i++) { foreach (var iword in Words) { if (words[i] == iword.text) { Console.WriteLine(iword.text + " " + iword.num); SaveStrs.Add(iword.text + " " + iword.num); break; } } } } else { for (; i < outPutNum; i++) { foreach (var iword in program.Words) { if (words[i] == iword.text) { Console.WriteLine(iword.text + " " + iword.num); SaveStrs.Add(iword.text + " " + iword.num); break; } } } } //輸出詞組 foreach (var word in MutipleWords) { Console.WriteLine(word.text + " " + word.num); SaveStrs.Add(word.text + " " + word.num); } }
運行效果:
單元測試:
斷點測試
性能分析圖
分析發現,Output()方法消耗最大,主要緣由是在輸出的時候運用了嵌套for循環。
異常及處理:
針對於文件輸入時發生的錯誤。
在此次結對編程項目中,最大的感覺就是1+1>2,若是一我的作,難度比較大。正所謂:兄弟齊心,其利斷金;尤爲是在找bug
方面。並且制定了代碼規範,兩我的的代碼都相互易讀。包括在最初的結構設計上,剛開始兩人各抒己見,通過一番商討以後,
設計出了雙方都滿意且最優的結構,在這裏結對編程的優點更爲明顯。