詞頻統計 ——Java

github地址 :https://github.com/NSDie/personal-projectjava

1、計劃表

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃
· Estimate · 估計這個任務須要多少時間 400 690
Development 開發
· Analysis · 需求分析 (包括學習新技術) 20 15
· Design Spec · 生成設計文檔 20 0
· Design Review · 設計複審 20 30
· Coding Standard · 代碼規範 (爲目前的開發制定合適的規範) 20 15
· Design · 具體設計 20 30
· Coding · 具體編碼 60 90
· Code Review · 代碼複審 20 30
· Test · 測試(自我測試,修改代碼,提交修改) 20 120
Reporting 報告
· Test Repor · 測試報告 120 240
· Size Measurement · 計算工做量 20 30
· Postmortem & Process Improvement Plan · 過後總結, 並提出過程改進計劃 60 90
合計 400 690

2、 解題思路

題目要求:文本讀寫、詞頻統計。git

文本讀寫用io庫 ,讀入字符串後用正則表達式或者本身寫字符串分割函數或者封裝好的分割函數來獲取單詞,詞頻統計用HashMap存,結果排序一下輸出。github

3、 設計實現

流程圖以下:
正則表達式

主函數裏調用各個功能。算法

單元測試:每一個函數依次測試,測試經過後;整合到主函數裏;而後用命令行窗口進行總體功能測試。數組

4、改進程序



目前沒怎麼改進程序,由圖中能夠看見,Tool類之調用了一次,就是在主函數統計那一次。其他的就是排序跟文本讀寫,HashMap的插入與查找的性能消耗。函數

5、 代碼說明

這是主函數,實現主要流程。性能

public class Main {

    public static void main(String[] args) {

        //文本讀入
        File file = new File(args[0]);
        FileRead fileRead = new FileRead();
        String data = fileRead.Input(file);

        //處理文本
        Tools tools = new Tools();
        int length = data.length();
        int wordAmount = tools.WordCount(data);
        int lines = data.split("\n").length;
        List<HashMap.Entry<String, Integer>> wordList = tools.WordSort();

        //文本輸出
        fileRead.Output(length,wordAmount,lines,wordList);
    }

}

Tool類中的詞頻統計:單元測試

調用了幾個函數,StringTokenizer()——split()函數的增強版,也是用來分割字符串的;replaceAll()——替換部分非字母數字字符。學習

public int WordCount(String data){
        int amount = 0;
        String data_l = data.toLowerCase(); // 所有字母轉小寫。
        String regex = "[^0-9a-zA-Z]"; //正則表達式,過濾非字母數字字符。
        data_l = data_l.replaceAll(regex, " "); //清洗文本。
        StringTokenizer words = new StringTokenizer(data_l); //分割文本成單詞。
        try {
            while (words.hasMoreTokens()) {
                String word = words.nextToken();
                if (word.length() >= 4) {  //判斷單詞長度是否大於等於4
                    if (Character.isLetter(word.charAt(0)) && Character.isLetter(word.charAt(1)) && Character.isLetter(word.charAt(2)) && Character.isLetter(word.charAt(3))) {  //判斷單詞前4個是否爲字母
                        amount++;
                        if (!wordCount.containsKey(word)) {
                            wordCount.put(word, new Integer(1));
                        } else {
                            int count = wordCount.get(word) + 1;
                            wordCount.put(word, count);
                        }
                    }
                }
            }
        }catch (Exception e){
            System.out.println("詞頻統計報錯:");
            System.out.println(e.getMessage());
        }
        return amount;
    }

其餘 FileRead就是一些文本處理,讀與寫。

具體見github

6、異常處理

有基本的容錯性:
根據輸入的文件名找不到文件。

文件過大,會數組越界沒法讀入,現已修復。順帶優化了讀寫的速度。
找了一個日誌文件測試了一下。

調優:

發現String經過"+"這種方法來拼接字符串是很是低效率的,因而用StringBuilder來代替。
附上幾回的測試圖:


7、總結

此次做業整體來講,花在寫報告跟測試的時間比較多。並且對於詞頻統計這一問題來講,之前作過相似的oj題,可是算法題跟項目又是兩碼事,算法題只要作到最優能過測試就行,可是項目不同。《構建之法》中提到的,「能證實所開發的軟件是能夠繼續維護和發展的」,項目不只僅作到知足用戶需求,還要作到低耦合,不管是方便之後別人參與進來仍是接手你的項目,都會更省時間。因此雖然花了不少時間,可是我以爲是有價值的。單元測試也是如此。

相關文章
相關標籤/搜索