結對第二次-文獻摘要熱詞統計

做業描述

課程 軟件工程1916|W(福州大學)
做業要求 結對第二次—文獻摘要熱詞統計及進階需求
結隊博客 221600328 221600106
Github地址 基礎需求
做業目標 實現一個可以對文本文件中的單詞的詞頻進行統計的控制檯程序。
具體分工 221600328:主要代碼及工做 221600106:部分代碼,編寫文檔

簽入記錄

做業正文


PSP表格

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

需求分析

WordCount基本需求
實現一個命令行程序,不妨稱之爲wordCount。
第一步、實現基本功能
輸入文件名以命令行參數傳入。例如咱們在命令行窗口(cmd)中輸入:
//C語言類
wordCount.exe input.txt
//Java語言
java wordCount input.txt
則會統計input.txt中的如下幾個指標
1.統計文件的字符數:java

  • 只須要統計Ascii碼,漢字不需考慮
  • 空格,水平製表符,換行符,均算字符

2.統計文件的單詞總數,單詞:至少以4個英文字母開頭,跟上字母數字符號,單詞以分隔符分割,不區分大小寫。c++

  • 英文字母: A-Z,a-z
  • 字母數字符號:A-Z, a-z,0-9
  • 分割符:空格,非字母數字符號
  • 例:file123是一個單詞,123file不是一個單詞。file,File和FILE是同一個單詞

3.統計文件的有效行數:任何包含非空白字符的行,都須要統計。git

4.統計文件中各單詞的出現次數,最終只輸出頻率最高的10個。頻率相同的單詞,優先輸出字典序靠前的單詞。github

5.按照字典序輸出到文件result.txt:例如,windows95,windows98和windows2000同時出現時,則先輸出windows2000正則表達式

  • 輸出的單詞統一爲小寫格式

6.輸出的格式爲
characters: number
words: number
lines: number
: number
: number
...
編程


解題思路

此次題目主要是兩個部分:字詞計數和文件讀寫,原本想用c++來進行編碼,後來發現使用Java更爲簡便,有許多類庫函數能夠直接調用來解決問題,因而就使用了Java。
思路主要是寫一個Count類,類裏包含各個小問題解決的方法,如CountCharacter,CountLine和CountWord。
使用BufferedReader讀文件,讀出來的數據用String存儲,對該字符串進行修改,獲取單詞及行數,最後重寫compare對單詞進行排序。
有了總體思路後,對每一個方法逐個擊破,便迎刃而解了。windows


代碼規範

一開始寫這個代碼十分不規範。。用的變量名簡直爲所欲爲,後面按照Java規範修改了一下,總體還行。app


設計說明

類圖
(https://img2018.cnblogs.com/blog/1593605/201903/1593605-20190315170442501-135307741.png)ide

流程圖
函數

模塊設計


模塊說明

傳入文件名,統計非空行數,統計字符數,統計單詞數,統計最多的10個單詞及其詞頻


方法說明

傳入文件名
CountCharacter:計算字符數
CountWord:計算單詞
CountLine:計算行數


關鍵代碼

統計單詞及計算詞頻部分,使用split正則表達式分詞,存入HashMap,重寫compare,存入List進行排序。

public int  CountWord() {
        int wordNum=0;
        String regex="[^A-Za-z0-9]";
        String textLowerCase= text.toLowerCase();
        String textcontents = textLowerCase.replaceAll(regex, " ");
        
        String[] textarrays = textcontents.split("\\s+");
        for(int i=0; i<textarrays.length;i++)
        {
            if(textarrays[i].length()>=4)
                if(Character.isLetter(textarrays[i].charAt(0)) && 
                        Character.isLetter(textarrays[i].charAt(0)) && 
                            Character.isLetter(textarrays[i].charAt(0)) && 
                                Character.isLetter(textarrays[i].charAt(0)))
            {
                wordNum++;
                if(!map.containsKey(textarrays[i]))
                    map.put(textarrays[i],1);
                else
                {
                    int num=map.get(textarrays[i]);
                    num++;
                    map.put(textarrays[i], num);
                }
            }
        }
        
        hotWords=Sort(map);
        return wordNum;
        
    }
    
    public static List<HashMap.Entry<String, Integer>> Sort(Map m){
    Map<String, Integer> map = new HashMap<String, Integer>();
    
    // 經過ArrayList構造函數把map.entrySet()轉換成list
    List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(m.entrySet());
    // 經過比較器實現比較排序
    Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
        @Override
        public int compare(Map.Entry<String,Integer> mapping1, Map.Entry<String, Integer> mapping2) {
            if(mapping1.getValue()==mapping2.getValue())
                return mapping1.getKey().compareTo(mapping2.getKey());//字典排序
            return mapping2.getValue()-mapping1.getValue();//從大到小
            
        }
    });
    
    return list;
    
}

異常處理

對於各個異常狀況都會打印異常信息,以下

catch (FileNotFoundException e) 
             {
             // TODO Auto-generated catch block
             e.printStackTrace();
             }catch (IOException e) 
             {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }

性能分析

如圖,大部分開銷來自於單詞技術部分。


單元測試

共設計了10組測試,分別有普通字符,換行符,空格,單詞大小寫,控制字符等。
如下是空白文件的測試,分別有統計單詞,行數,字符的測試。



改進思路

如圖,在IO上有巨大的開銷,主要在計算行數時又訪問了一遍文件,致使過分的IO,性能降低,應先將文件數據暫存,後續對該文件進行訪問,減小IO,提升性能。
另外分割字符的函數split開銷也挺大,或許使用stringTokenizer進行切分能提升性能。


遇到的困難和解決方法:

  • 需求的理解
    • 解決方法:無可避免又在需求上產生疑問,果真對需求的清晰理解是首先,也是最重要的一步,經過與同窗助教探討解決問題。
  • 使用性能分析,單元測試工具及git的使用
    • 解決方法:首次使用這些工具,對工具的不熟悉,經過詢問同窗及上網查找資料解決。
  • 編碼能力不足
    • 解決方法:我的編碼能力不足,以致於編寫代碼花了不少的時間,定痛改前非,提升編程能力

評價隊友

和隊友溝通良好,合做愉快!

相關文章
相關標籤/搜索