zoukankan      html  css  js  c++  java
  • 统计文本中单词出现的频率

    需求:写一个程序,分析一个文本文件中各个词出现的频率,并且把频率最高的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方法使用的时间明显的改进。整个程序的时间消耗也有了较大的提高。现在最耗时的消耗是对文件的读取和使用正则表达式的匹配处。

  • 相关阅读:
    姐姐的vue(1)
    LeetCode 64. Minimum Path Sum 20170515
    LeetCode 56. 56. Merge Intervals 20170508
    LeetCode 26. Remove Duplicates from Sorted Array
    LeetCode 24. Swap Nodes in Pairs 20170424
    LeetCode 19. Remove Nth Node From End of List 20170417
    LeetCode No.9 Palindrome Number 20170410
    LeetCode No.8. String to Integer (atoi) 2017/4/10(补上一周)
    LeetCode No.7 Reverse Integer 2017/3/27
    LeetCode No.4 Median of Two Sorted Arrays 20170319
  • 原文地址:https://www.cnblogs.com/wangrd/p/3603816.html
Copyright © 2011-2022 走看看