文章出處

需求:寫一個程序,分析一個文本文件中各個詞出現的頻率,并且把頻率最高的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和內存。

6(_8ER1V2GR]C`F0WPC]M1Y                            HT%LOV`RW4U7Y{6}GZFD{)R

可以看計算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.性能分析

Z%TA(N07HFU7WKO6PK52]ZA                       78CUUM5S(XU~$4H%D(ZBSIO

可以看出,update方法使用的時間明顯的改進。整個程序的時間消耗也有了較大的提高。現在最耗時的消耗是對文件的讀取和使用正則表達式的匹配處。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()