天天看點

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

作業描述

課程 軟體工程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 生成設計文檔 70
Design Review 設計複審 80
Coding Standard 代碼規範 (為目前的開發制定合适的規範) 30 20
Design 具體設計
Coding 具體編碼 770 850
Code Review 代碼複審 120 100
Test 測試(自我測試,修改代碼,送出修改)
Reporting 報告 160
Test Repor 測試報告 35
Size Measurement 計算工作量 25
Postmortem & Process Improvement Plan 事後總結, 并提出過程改進計劃 55
合計 2180 2325

需求分析

WordCount基本需求

實作一個指令行程式,不妨稱之為wordCount。

第一步、實作基本功能

輸入檔案名以指令行參數傳入。例如我們在指令行視窗(cmd)中輸入:

//C語言類

wordCount.exe input.txt

//Java語言

java wordCount input.txt

則會統計input.txt中的以下幾個名額

1.統計檔案的字元數:

  • 隻需要統計Ascii碼,漢字不需考慮
  • 空格,水準制表符,換行符,均算字元

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

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

3.統計檔案的有效行數:任何包含非空白字元的行,都需要統計。

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

5.按照字典序輸出到檔案result.txt:例如,windows95,windows98和windows2000同時出現時,則先輸出windows2000

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

6.輸出的格式為

characters: number

words: number

lines: number

: number

...

解題思路

這次題目主要是兩個部分:字詞計數和檔案讀寫,本來想用c++來進行編碼,後來發現使用Java更為簡便,有許多類庫函數可以直接調用來解決問題,于是就使用了Java。

思路主要是寫一個Count類,類裡包含各個小問題解決的方法,如CountCharacter,CountLine和CountWord。

使用BufferedReader讀檔案,讀出來的資料用String存儲,對該字元串進行修改,擷取單詞及行數,最後重寫compare對單詞進行排序。

有了整體思路後,對每個方法逐個擊破,便迎刃而解了。

代碼規範

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

設計說明

類圖

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

流程圖

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

子產品設計

子產品說明

傳入檔案名,統計非空行數,統計字元數,統計單詞數,統計最多的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的使用
    • 解決方法:首次使用這些工具,對工具的不熟悉,通過詢問同學及上網查找資料解決。
  • 編碼能力不足
    • 解決方法:個人編碼能力不足,以至于編寫代碼花了很多的時間,定痛改前非,提高程式設計能力

評價隊友

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