文章出處
文章列表
需求:寫一個程序,分析一個文本文件中各個詞出現的頻率,并且把頻率最高的10個詞打印出來。文本文件大約是30KB~300KB大小。
1.思路
①數據結構:Word類封裝單詞String和頻率count,并重寫equals方法,以key(String)相同則認為Word對象相同。
先從dictionary.txt一行一行讀取字符串,使用正則表達式過濾出單詞并存放在ArrayList中,遍歷list,將每個string都封裝成Word放入一個WordList中;再使用Collections工具類的sort()方法添加一個按照count值的comparator進行排序。
2.分析
使用YourKit Java Profiler進行性能分析。CPU和內存。
可以看計算340KB的文本用了561毫秒。從圖中可以看出,update1方法相當耗時間。因為方法內部,將每一個string進行封裝成對象,并使用了indexOf()方法尋找位置后更改。
3.改進分析
如果繼續不使用ArrayList存儲Word來尋找,而使用HashMap來將String作為key,count作為value,在update方法中,就可以直接使用map的get方法判斷是否存在唯一的key(string)。最后使用Map的根據count排序即可。
4.改進實現
public class CountOfWordsTest1 { public static void main(String[] args) { test(); } public static void test() { ArrayList<String> list = readFromFile(); List<Map.Entry<String, Integer>> WordList = countOfWords(list); printList(WordList); } /* * @Description read from file and split String with regex * @return the ArrayList contains words */ @SuppressWarnings("resource") public static ArrayList<String> readFromFile() { ArrayList<String> list = new ArrayList<String>(); BufferedReader br = null; StringBuilder sb = null; try { br = new BufferedReader(new InputStreamReader(new FileInputStream( "./src/dictionary.txt"))); sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line + " "); } } catch (IOException e) { e.printStackTrace(); } // 提取讀出來的單詞(出去特殊字符) String regEx = "[a-zA-Z]+"; Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(sb); while (m.find()) { String temp = m.group(); // System.out.println(temp); list.add(temp); } return list; } /* * @Description get every word from list and add it to map,then sorted * @param list contains all the word * @return map with key-String and value-count */ public static List<Map.Entry<String, Integer>> countOfWords( ArrayList<String> list) { Map<String, Integer> adjWords = new HashMap<String, Integer>(); for (int i = 0; i < list.size(); i++) { String temp = list.get(i); update(adjWords, temp); } // 將adjWords并轉換成list按count排序 ArrayList<Map.Entry<String, Integer>> WordList = new ArrayList<Map.Entry<String, Integer>>( adjWords.entrySet()); Collections.sort(WordList, new Comparator<Map.Entry<String, Integer>>() { @Override public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { Integer temp1 = o1.getValue(); Integer temp2 = o2.getValue(); return temp2.compareTo(temp1); } }); return WordList; } /* * @Description count++ if existed or put(string,1) to the map * @param map adjWords to record string and count * @param s the new String */ public static void update(Map<String, Integer> map, String s) { Integer count = map.get(s); if (count == null) { count = 1; } else { count++; } map.put(s, count); } /* * @Description print the list Sorted by count */ public static void printList(List<Map.Entry<String, Integer>> WordList) { // for (Map.Entry<String, Integer> entry : map.entrySet()) { // String key = entry.getKey(); // Integer value = entry.getValue(); // System.out.println(key + "..." + value); // } for (int i = 0; i < 10; i++) { Map.Entry<String, Integer> entry = WordList.get(i); String key = entry.getKey(); Integer value = entry.getValue(); System.out.println(key + "..." + value); } } }
5.性能分析
可以看出,update方法使用的時間明顯的改進。整個程序的時間消耗也有了較大的提高。現在最耗時的消耗是對文件的讀取和使用正則表達式的匹配處。
文章列表
全站熱搜
留言列表