GitHub項目地址 | 這裏 |
---|---|
合做同窗做業地址 | 這裏 |
PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 30 | 30 |
Estimate | 估計這個任務須要多少時間 | 1510 | 1925 |
Development | 開發 | 990 | 1325 |
Analysis | 需求分析 (包括學習新技術) | 90 | 100 |
Design Spec | 生成設計文檔 | 60 | 60 |
Design Review | 設計複審 (和同事審覈設計文檔) | 20 | 30 |
Coding Standard | 代碼規範 (爲目前的開發制定合適的規範) | 10 | 20 |
Design | 具體設計 | 30 | 25 |
Coding | 具體編碼 | 900 | 1200 |
Code Review | 代碼複審 | 60 | 100 |
Test | 測試(自我測試,修改代碼,提交修改) | 240 | 300 |
Reporting | 報告 | 30 | 25 |
Test Report | 測試報告 | 10 | 5 |
Size Measurement | 計算工做量 | 30 | 20 |
Postmortem & Process Improvement Plan | 過後總結, 並提出過程改進計劃 | 30 | 40 |
合計 | 1510 | 1925 |
1)首先咱們須要讀取指定的文件,而且將文本文件中的內容提出出來,進行操做。這裏使用C#的IO流來進行文件操做。html
2)根據要求以及難易程度,咱們首先解決文本的行數以及字符數的統計。這裏使用正則表達式進行處理。git
3)對於單詞的統計咱們在完成行數和字符數統計以後,決定使用集合來處理單詞,可是發現單詞是可以處理了,可是得不到單詞出現的次數,因此咱們轉而使用字典集(Dictionary)來進行處理,字典集爲咱們提供了不少方便的功能。程序員
先用ArrayList集合存儲全部單詞,包括重複的單詞,都存進去,可是是按照要求存儲單詞,也就是說必須四個英文字母開頭的單詞咱們才存儲,這裏就用到正則表達式來解決。github
將存儲好的單詞通過遍歷放進字典集,這樣咱們就獲得了符合要求的全部單詞的一個字典集,而且也獲得了它們出現的次數,而後在對它們進行排序,就能夠獲得最終符合要求的前10個單詞了。正則表達式
4)基礎功能實現後,又開始實現新添加的功能,命令行操做以及輸出指定長度的詞組。算法
因爲使用條件判斷語句不可以很好的知足命令行操做的要求,咱們通過查找資料,發現了可使用一個第三方的工具包來幫助咱們。這裏@命令行解析,經過這個工具包,咱們實現了命令行操做。編程
對於指定長度的詞組,實現方式和單詞的存儲大體相同。
總體程序流程圖以下圖所示
緩存
經過正則表達式存儲符合要求單詞函數
/* * 按要求存儲可用單詞 */ public ArrayList Splitwords(string text) { ArrayList al = new ArrayList(); MatchCollection matchs = Regex.Matches(text, @"\b[a-zA-Z]{4,}\w*"); foreach (Match match in matchs) { al.Add(match.Value); } return al; } public ArrayList Splitlenth(int lenth, string text) { string b = lenth.ToString(); string pattern = "\\b\\w{"+b+"}\\s"; ArrayList al = new ArrayList(); MatchCollection matchs = Regex.Matches(text, pattern); foreach (Match match in matchs) { al.Add(match.Value); } return al; }
統計每一個單詞出現的次數工具
/* * 統計每一個單詞出現的次數 */ public Dictionary<string, int> countWords(ArrayList arrayList) { Dictionary<string, int> nary = new Dictionary<string, int>(); foreach (string word in arrayList) { if (nary.ContainsKey(word)) { nary[word]++; } else { nary.Add(word, 1); } } return nary; }
按值排序
/* * 按值排序 */ public Dictionary<string, int> sort(Dictionary<string, int> nary) { var result = from pair in nary orderby pair.Value descending, pair.Key ascending select pair; Dictionary<string, int> bronary = new Dictionary<string, int>(); foreach (KeyValuePair<string, int> pair in result) { bronary.Add(pair.Key, pair.Value); } return bronary; }
指定輸出詞組長度
/* * 指定詞組長度 */ public Dictionary<string,int> msort(ArrayList al,int size) { Dictionary<string, int> nary = new Dictionary<string, int>(); ArrayList bl = new ArrayList(); int i = 0; while(i<=al.Count-size) { string str = null; var result = al.GetRange(i, size); foreach (var n in result) { str += n.ToString()+" "; } bl.Add(str); i++; } foreach (string word in bl) { if (nary.ContainsKey(word)) { nary[word]++; } else { nary.Add(word, 1); } } return nary; }
代碼規範是程序員的一種編程習慣,良好的編程習慣,不只能天然地產生幾乎沒有bug的代碼,並且在代碼交接時,也方便繼任者的閱讀.這是咱們的代碼規範
1)接口設計:將三個基本功能,分爲三個類,下降耦合度,便於進行單元測試,以及代碼的修改,這樣就能夠在修改其中一個功能的時候,不影響其餘功能。可是也並無把全部的功能都分離開,統計單詞裏面就有不少個功能,類多了會增長整個程序的繁瑣程度,也會下降代碼的可讀性。
2)功能封裝:按照要求將三個基本功能進行封裝,封裝成一個ClassLibrary,而且讓它生成dll文件,這樣程序就能夠直接引用封裝好的功能,更能減小代碼量,下降耦合度。
在咱們的Winform程序當中,咱們引用了封裝好的統計功能,減小了重複代碼量。
接口的封裝讓咱們的功能的實現更加的隱蔽,用戶在引用咱們的dll時,不會看見咱們的代碼。
我在審查隊友代碼的時候,發現「統計單詞」這一模塊的排序實現有問題,不知足給定的要求。排序功能只實現了詞頻的排序,可是有相同詞頻的不一樣單詞沒有按照字典序排序。
最第一版本運行截圖:
能夠看到,在第一個版本這裏,"child"和"little"的詞頻都是出現一次,可是按照字典序,"child"應該排在"little"前面輸出。
改進後版本運行截圖:
改進後,"again"和"made"詞頻都是出現兩次,實現了字典序輸出相同詞頻的單詞排序。
內存溢出問題
在進行小文本測試時,代碼能夠正常實現預約功能,並輸出;當咱們使用一個大小爲28MB的txt文本時,通過進2分鐘的運行,拋出內存溢出錯誤。
在多方查找資料以及嚴密分析以後,發現了咱們代碼中存在的問題。在characSum函數中,對大量數據進行處理時,須要接二連三的實例化很是多個對象,而且它們一直會在緩存區,直到函數執行完畢纔會被釋放,這樣就會致使內存一直被擠壓,最後就會致使內存不夠用,進而拋出內存溢出的錯誤。
在瞭解了問題觸發的機制後,在處理數據時,咱們再也不使用實例化對象的方式,而是經過統計字符串的整個長度來獲得字符數的大小,而且通過實驗,達到了預期目的。
測試三個基本功能。
對於行數以及字符數測試,咱們進行簡單的數據構造,測試數據要可以靠人工數出來。
對於單詞統計測試,咱們一樣進行簡單的數據構造。
1)大小寫同時出現。
2)數據中要有file123和123file這類詞。
3)數據中心要有小於4個字符的詞。
命令行輸入不符合要求的話,會提示出錯,須要從新輸入命令行。
根據代碼效能分析的結果,設置內存溢出異常處理。
在結對以後,選定了兩方都有空的時間進行討論,根據PSP表格預估時間,討論出項目需求,代碼設計,根據各自水平進行分工,完成代碼先進性自省,而後交換代碼進行復審,最後彙總生成.exe文件進行單元測試並不斷提交進度,最後撰寫博客。
這是咱們在一塊兒進行代碼測試分析
導入單詞文本(-i命令行)
直接輸入單詞
自定義詞組長度(-m)
自定義輸出高頻單詞數量(-n)
導出統計結果
一、 兩人在合做過程當中彼此交流,能更敏銳地發現代碼中出現的漏洞,及時改正錯誤,提升工做效率;
二、 兩人合做相較於多人團隊合做而言,更能促進彼此的交流,由於兩人合做過程當中,有什麼問題能夠直接提出,並在兩人商討以後獲得滿意的結論,若參與者數量太多,反而很差調配;
三、 雖然咱們兩我的的水平有必定差距,可是咱們彼此信任,共同努力,最終仍是實現了一個比較理想的算法,這是咱們共同的勞動結果;
四、能和同伴一塊兒交流,一同解決問題是一件挺好的事,兩我的一塊兒寫代碼思路也會更開闊。我以爲若是當一我的沒有思路了,或者實現一個比較複雜的邏輯部分代碼的時候,能夠採用結對編程的方式。