做業要求連接 | 做業地址 |
---|---|
夥伴博客 | 李涵 |
Github地址 | github |
(1)PSP表格html
PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 30 | 30 |
· Estimate | · 估計這個任務須要多少時間 | 30 | 30 |
Development | 開發 | 770 | 720 |
· Analysis | · 需求分析 (包括學習新技術) | 300 | 240 |
· Design Spec | · 生成設計文檔 | 30 | 20 |
· Design Review | · 設計複審 (和同事審覈設計文檔) | 30 | 20 |
· Coding Standard | · 代碼規範 (爲目前的開發制定合適的規範) | 20 | 15 |
· Design | · 具體設計 | 30 | 30 |
· Coding | · 具體編碼 | 300 | 315 |
· Code Review | · 代碼複審 | 30 | 40 |
· Test | · 測試(自我測試,修改代碼,提交修改) | 30 | 40 |
Reporting | 報告 | 150 | 120 |
· Test Report | · 測試報告 | 60 | 45 |
· Size Measurement | · 計算工做量 | 30 | 30 |
· Postmortem & Process Improvement Plan | · 過後總結, 並提出過程改進計劃 | 60 | 45 |
合計 | 950 | 900 |
(2)代碼規範:node
命名規範:1.類名首字母要大寫,使用可以反映類功能的名詞或名詞短語命名類。git
2.類成員變量首單詞小寫,變量名前可加_前綴。github
3.方法名第一個字符要大寫,且應使用動詞或動詞短語。編程
4.參數首字符小寫,採用描述性參數名稱。ide
5.接口名稱要有意義,接口修飾符只能用public和internal。函數
6.每條語句至少佔一行,過長語句斷爲兩行顯示。性能
7.語句嵌套不超過3層。單元測試
詳細代碼規範見:代碼規範學習
(3)結對過程:非擺拍討論、結對編程照片:
線下分工、討論、結對編程;工做日時細小問題線上解決。
(4)解題思路及關鍵代碼展現:
大致功能結構圖:
統計字符數、單詞數、行數模塊:
public long charactersnumber = 0; //字符數 public long wordsnumber = 0; //單詞數 public long linesnumber = 0; //行數 //數據統計 public void Calculate(string dataline, WordTrie wtrie) { if (string.IsNullOrEmpty(dataline)) return; string word = null; for (int i = 0, len = dataline.Length; i < len; i++) { char unit = dataline[i]; if (unit >= 65 && unit <= 90){ unit = (char)(unit + 32); } //大寫轉小寫 if ((unit >= 48 && unit <= 57) || (unit >= 97 && unit <= 122)){ word = String.Concat(word, unit); } else{ if (!string.IsNullOrEmpty(word)){ //判斷是否爲詞尾後的字符 if (word[0] >= 97 && word[0] <= 122){ //首字符是否爲字母 wtrie.Insert(word); } word = null; } } } if (!string.IsNullOrEmpty(word)) //判斷行尾是否有單詞 { if (word[0] >= 97 && word[0] <= 122){ //首字符是否爲字母 wtrie.Insert(word); } word = null; } this.linesnumber++; //統計行數 this.wordsnumber = wtrie.CountSum; //統計單詞數 this.charactersnumber += dataline.Length; //統計字符數 }
詞頻排序:
public List<ListUnit> Sort() { TrieNode node = _Root; List<ListUnit> WordList = new List<ListUnit>(); WordList = WordPreOrder(node, WordList); //按詞頻降序排列,若詞頻相等按字典序排列 WordList.Sort((a, b) => { if (a.WordNum.CompareTo(b.WordNum) != 0) return -a.WordNum.CompareTo(b.WordNum); else return a.Word.CompareTo(b.Word); }); return WordList; }
單詞表生成:
private List<ListUnit> WordPreOrder(TrieNode node, List<ListUnit> WordList) { if (node.PrefixNum == 0) { return WordList; } if (node.WordNum != 0) { ListUnit unit = new ListUnit(); unit.Word = node.Word; unit.WordNum = node.WordNum; WordList.Add(unit); } foreach (char key in node.Sons.Keys) { WordList = WordPreOrder(node.Sons[key], WordList); } return WordList; }
讀取並統計文件:
public string pathIn; public string pathOut; //按行讀取輸入文件並統計 public WordCalculate Input(WordCalculate datanumber, WordTrie wtrie) { FileStream fs = null; StreamReader sr = null; String dataline = String.Empty; try { fs = new FileStream(this.pathIn, FileMode.Open); sr = new StreamReader(fs); while ((dataline = sr.ReadLine()) != null) { datanumber.Calculate(dataline, wtrie); //按行統計數據 } } catch { Console.WriteLine("文檔讀取失敗!"); } finally { if (sr != null) { sr.Close(); } if (fs != null) { fs.Close(); } } return datanumber; }
將結果輸出文件:
//將統計數據寫到輸出文件 public void Output(WordCalculate datanumber, WordTrie wtrie) { FileStream fs = null; StreamWriter sw = null; List<WordTrie.ListUnit> WordList = new List<WordTrie.ListUnit>(); try { fs = new FileStream(this.pathOut, FileMode.Create); sw = new StreamWriter(fs); WordList = wtrie.Sort(); sw.WriteLine(String.Concat("characters:", datanumber.charactersnumber, "\n")); sw.WriteLine(String.Concat("words:", datanumber.wordsnumber, "\n")); sw.WriteLine(String.Concat("lines:", datanumber.linesnumber, "\n")); sw.WriteLine("\n詞頻\t單詞\n"); Console.WriteLine(String.Concat("字符總數", datanumber.charactersnumber, "\n")); Console.WriteLine(String.Concat("單詞總數", datanumber.wordsnumber, "\n")); Console.WriteLine(String.Concat("有效行數", datanumber.linesnumber, "\n")); Console.WriteLine("\n詞頻\t單詞\n"); for (int i = 0; (i < 10 && i < datanumber.wordsnumber); i++) { sw.WriteLine(String.Concat(WordList[i].WordNum, '\t', WordList[i].Word, "\n")); Console.WriteLine(String.Concat(WordList[i].WordNum, '\t', WordList[i].Word, "\n")); } } catch { Console.WriteLine("文檔寫入失敗!"); } finally { if (sw != null) { sw.Close(); } if (fs != null) { fs.Close(); } } }
代碼較多,只展現部分代碼,完整代碼已提交。
運行結果:輸入文件
輸出結果:
(5)性能分析及改進:
初期初版咱們全部功能代碼寫在一個Main函數中,意在與功能獨立、鬆耦合後進行性能對比,Main函數資源佔比巨大。
第二版本實現基礎功能獨立後生成性能分析報告:
(6)單元測試:詳情見隊友
(7)異常處理:
代碼中的異常處理機制:進行文檔讀取、寫入的異常機制處理
(8)附加功能:
.-m 參數設定統計的詞組長度
.-n參數設定輸出的單詞數量
.-i 參數設定讀入的文件路徑
.-o 參數設定生成文件的存儲路徑
多參數的混合使用等新增功能的實現,使用了commandline程序
(9)代碼複審:
兩人結對編程,編程過程當中兩人互相監督,且共同查閱相關資料,參考的文章也大抵相同。於是在代碼複審過程當中並未發現諸如結構、功能性問題等大問題。但複審仍是發現了很多小問題,諸如相關代碼規範執行的並不徹底到位,有多處代碼冗餘狀況。互通代碼時路徑問題也沒溝通好,但都進行了及時修改。
(10)我的感悟:
兩人結對編程效率確實比一我的高,當遇到問題時何以相互探討,一塊兒查閱資料;一人在寫代碼時會同時有兩雙眼睛進行監督、糾錯、思考;即便遇到困難內心也不會太慌張,通常經過討論、百度便可解決。體驗最真實,結對編程1+1確實是>2的
同時對結對編程流程、C#語言有了更深刻的瞭解,自身的編程素質有了很大提升。經過本次實驗做業收穫良多。