根據實驗二 軟件工程我的項目的要求本次軟件項目的需求有如下幾點:
1.程序可讀入任意英文文本文件,該文件中英文詞數大於等於1個,程序須要很壯健,能讀取容納英文原版《哈利波特》10萬詞以上的文章。
2.指定單詞詞頻統計功能:用戶可輸入從該文本中想要查找詞頻的一個或任意多個英文單詞,運行程序的統計功能可顯示對應單詞在文本中出現的次數和柱狀圖。
3.高頻詞統計功能:用戶從鍵盤輸入高頻詞輸出的個數k,運行程序統計功能,可按文本中詞頻數降序顯示前k個單詞的詞頻及單詞。
4.統計該文本全部單詞數量及詞頻數,並能將單詞及詞頻數按字典順序輸出到文件result.txt。html
1.對於需求一、需求4須要有讀入文本數據、向文本輸出數據的功能。
2.對於需求3和需求4須要有排序的功能
3.整個項目要求有對詞頻進行統計的功能java
1.本次項目有兩個類:
(1)main.java主要實現文本讀入和功能選擇的功能,根據用戶輸入的選擇調用function.java中相應的功能函數。
(2)function.java實現排序(sort函數),查找單詞詞頻顯示柱狀圖(find函數),輸出前n個高頻詞(print函數),單詞及詞頻數按字典順序輸出到文件result.txt(Sort函數)四個主要功能。
2.數據結構:
本次項目採用TreeMap存儲從文本讀入的數據,用LinkedList進行詞頻排序。
3.流程圖:
本項目總的流程圖爲:
git
1.顯示單詞詞頻和柱狀圖
github
2.輸出前K個高頻詞
數組
3.向result.txt寫入單詞和詞頻
數據結構
1.文件讀入並統計詞頻模塊化
// 讀取要處理的文件 BufferedReader b = new BufferedReader(new FileReader("src/HarryPotter.txt")); //<單詞:詞頻> Map<String, Integer> map = new TreeMap<String, Integer>(); String value= b.readLine(); while (value!= null) { //處理標點符號 String[] words = value.split("[【】、.。,\"!--;:?\'\\] ]"); for (int i = 0; i < words.length; i++) { //將大寫字母轉換爲小寫字母 String key = words[i].toLowerCase(); if (key.length() > 0) { if (!map.containsKey(key)) { map.put(key, 1); } else { int k = map.get(key)+1;// 若是不是第一次出現,就把k值++ map.put(key, k); } } } value = b.readLine(); }
2.按詞頻或字母排序函數
Set<Entry<String,Integer>> m= map.entrySet(); LinkedList<Entry<String, Integer>> List = new LinkedList<Entry<String,Integer>>(m); //按值排序 if(a==2) { Collections.sort(List, new Comparator<Entry<String,Integer>>() { public int compare(Entry<String, Integer> a, Entry<String, Integer> b) { return b.getValue().compareTo(a.getValue()); } }); //按鍵排序 else if(a==3) { Collections.sort(List, new Comparator<Entry<String,Integer>>() { public int compare(Entry<String, Integer> a, Entry<String, Integer> b) { return a.getKey().compareTo(b.getKey()); } }); } //排序後存入Map中 for(Entry<String,Integer> entry: List) { Map.put(entry.getKey(), entry.getValue()); } }
3.向文件寫入單詞詞頻測試
//建立文件 File file = new File("result.txt"); //向文件寫入 FileWriter f = new FileWriter(file.getAbsoluteFile()); for(Entry<String,Integer> w: Map.entrySet()) { f.write(w.getKey() + "/" + w.getValue()+" "); } f.close(); System.out.println("結束!");
1.本次項目中各功能在function類中,用函數實現各個功能,經過用戶輸值調用相應的功能,以此來實現模塊化。
2.在剛開始設計讀入文件數據的時候,打算採用二維數組存放單詞,相應的一維數組存放個數,但發現數組太大,並且在進行排序的時候不方便所以採用了<鍵:值>的映射存放數據。
3.在進行柱狀圖繪製時,因爲除以500後的小數沒法表示,只能表示出大概的趨勢。編碼
任務內容 | 計劃完成時間(min) | 實際完成時間(min) |
---|---|---|
計劃 | 5 | 3 |
規劃工做步驟 | 10 | 7 |
開發 | 173 | 202 |
需求分析 | 10 | 15 |
生成文檔 | 5 | 10 |
設計複審 | 3 | 2 |
代碼規範 | 20 | 15 |
具體編碼 | 100 | 120 |
代碼複審 | 10 | 5 |
測試 | 25 | 40 |
報告 | 15 | 12 |
測試報告 | 5 | 7 |
計算報告量 | 5 | 2 |
過後總結 | 5 | 3 |
從表中能夠看出在編碼階段時間較多且和本身估計的時間差距較大,主要是在進行數據結構的選擇上錯誤,浪費大量時間進行修改,而且因爲長時間沒有使用Java,全部有些生疏,在測試階段時間也比較長,本身開始的邏輯上有些混亂致使結果不正確顯示,一步步的調試最終實現了相應功能。
點擊源碼可查看項目源代碼