首先,感謝鄒老師的關注和回復。根據鄒老師和楊老師的回復,我更新了周六的程序。
鄒老師的問題我理解為如下兩方面:
1. 引入stop word 該如何改進程序
2. 程序耗時最多的地方是哪里?如何解釋?
楊老師的問題我的理解有如下方面:
- 對hash 和 array性能進行對比
- 列特性和需求,考慮核心接口。
根據老師們的建議,目前對程序進行了如下修改:
- 將讀寫文件的操作單獨用一個類實現。MyFile.java
- 修改了讀源文件時候的處理方式,將String 改成了StringBuffer,原因是計算版本1程序的運行時間時,發現讀文件花費了很長的時間,看程序發現是因為讀文件時用到了String,影響了性能。
- 將程序改進,不同功能的模塊由不同函數完成。
-
根據鄒老師提出的問題,添加了新的函數用來加載stoplist.txt。同時在詞頻統計函數中進行判斷。
注:因為之前對stop word這個術語不理解,通過上網查詢獲知stop word的意思。換成自己的理解就是:對於一個英文著作中,有很多如am is are之類的詞,我們統計這樣詞的出現頻率並沒有太大意義,所以這樣的詞可以出現在stoplist列表中,統計的時候只算一次,或者忽略不計就可以了。我猜想這可能是鄒老師出這個問題的初衷,是這樣嗎?
-
修改后,主函數直接按照算法的流程圖調用各個函數:
- 獲取stop列表
- 獲取詞頻統計源文件內容
- 預處理源文件內容
- 詞頻統計
- 將統計結果寫入結果文件
思考:
對於鄒老師提到的問題2,通過運行程序,發現耗時最多的地方是預處理這個函數,在我的電腦上,各個函數的運行時間如下:
getStopList |
2ms |
getSourceContent |
28ms |
pretreatmentContent |
447ms |
getFreq |
53ms |
writeFile |
90ms |
關於楊老師提到的比較hash和array性能這個思考,待有時間時繼續。
最后附上程序:
MyFile.java
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.*;
public class MyFile {
public static String readFile(String path) { StringBuffer result = new StringBuffer(); try { BufferedReader br = new BufferedReader(new FileReader( new File(path))); String tmp = null; while ((tmp = br.readLine()) != null) { result.append(tmp); result.append(" "); } br.close(); } catch (IOException e) { e.printStackTrace(); } return result.toString(); }
public static void writeFile(List<Map.Entry<String, Integer>> lst) { try { BufferedWriter bw = new BufferedWriter(new FileWriter(new File( System.getProperty("user.dir") + "//result.txt"))); for(int i=0;i<lst.size();i++) { bw.append(lst.get(i).getKey()+":"+lst.get(i).getValue()+"\n"); } bw.flush(); bw.close(); } catch (IOException e) {
} } } |
WordFreqStatistics.java
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry;
public class WordFreqStatistics {
public static String sourceFilePath = System.getProperty("user.dir") + "//anna.txt"; public static String stopWordFilePath = System.getProperty("user.dir") + "//stoplist.txt"; public static Map<String,Integer> mp = new HashMap<String, Integer>(); public static Set<String> stop = new HashSet<String>(); public static String words[] = null; public static String sourceContent =null;
public static void getStopList() { String stopContent = MyFile.readFile(stopWordFilePath); String stopWords[] = stopContent.split("\\s+|\\r|\\n|\\t"); for(String word : stopWords) { stop.add(word); } }
public static String getSourceContent(String filepath) { return MyFile.readFile(filepath); }
public static String[] pretreatmentContent(String content) { content = content.toLowerCase(); content = content.replaceAll("[^A-Za-z]", " "); content = content.replaceAll("\\s+", " ");
return content.split("\\s+"); }
public static void getFreq(String[] words) { for(int i=0;i<words.length;i++) { if(!stop.contains(words[i])) { if((mp.get(words[i]))!=null) { int value = ((Integer)mp.get(words[i])).intValue(); value++; mp.put(words[i], new Integer(value)); } else{ mp.put(words[i], new Integer(1)); } } } }
public static List<Map.Entry<String,Integer>> sort() { ArrayList<Entry<String, Integer>> lst = new ArrayList<Entry<String, Integer>>( mp.entrySet()); Collections.sort(lst,new Comparator<Object>() { public int compare(Object e1,Object e2) { int v1 = Integer.parseInt(((Entry<String, Integer>) e1) .getValue().toString()); int v2 = Integer.parseInt(((Entry<String, Integer>) e2) .getValue().toString()); return v2-v1; } }); return lst; }
public static void main(String[] args) { getStopList(); sourceContent = getSourceContent(sourceFilePath); words = pretreatmentContent(sourceContent); getFreq(words); MyFile.writeFile(sort()); }
} |
待續