前几天写了一个词频统计的小工程(如果想了解的话。请看我上一篇博客),今天我根据邹欣老师的提出的一个需求进行了修改,找出一篇文章中出现最多的两个词(连在一起的,暂且忽略词义分析,是否是词组)。
工程的环境:myeclipse
我的处理方案是这样的:首先把一篇文章读到一个StringBuilder(已经去除了标点),然后再分割成数组fullTextArray.针对这个数组我们需要做一些特殊处理,因为连词如:I'm,don't,it's等,经过java正则标点替换后会变成“I m”,"don t".然后,我把两个单词看作一个整体,形成一个新的数组twoWordArray.剩下的结合上一篇词频统计的一样了。
这个程序尚有许多可以改进的地方:1.读取文章的时候,我才去的方案是把整篇文章读入StringBuilder中,对内存有一定要求,如果文件过大,可能造成内存溢出。如果大家有什么好的解决方案,欢迎大家讨论。
2. 针对寻找两个连在一起的单词,我的算法有点笨拙。希望大家提出建议。
最后附上我的代码:
/** * 统计两个单词的词频统计 * @param filePath * @return */ public static Map<String,Integer> readtxtFile2(String filePath) { Map<String, Integer> index_map = new HashMap<String, Integer>(); BufferedReader reader = null; File file = new File(filePath); try { FileInputStream in = new FileInputStream(file); reader = new BufferedReader(new InputStreamReader(in, "UTF-8")); StringBuilder buffer = new StringBuilder(); String lineText = ""; while((lineText=reader.readLine())!= null) {//读取文件 lineText = lineText.replaceAll("\\p{Punct}", " ").trim();//去除标点符号 // lineText = lineText.replaceAll("\\pP", " ").trim(); // System.out.println(lineText); buffer.append(lineText); buffer.append(" "); } // System.out.println(buffer.toString().trim()); //处理数据,针对特殊数据 如:I'm don't... String[] lineArray = buffer.toString().trim().split(" "); ArrayList<String> token = new ArrayList<String>(); for(String buff:lineArray) { String temp = buff.toLowerCase().trim(); if(temp.length()>0&&temp!="m"&&temp!="t"&&temp!="ve"&&temp!="s"&&temp!="ll"&&temp!="d") { token.add(buff); } } StringBuilder twoWordArrayStr = new StringBuilder(); for(int i=0;i<token.size()-1;i++) { twoWordArrayStr.append(token.get(i)+token.get(i+1)+"&"); } /*String temp1,temp2 = ""; for(int i = 0;i < lineArray.length-1; i++) { temp1 = lineArray[i].toLowerCase().trim(); temp2 = lineArray[i+1].toLowerCase().trim(); if(temp1.length()>0) { twoWordArrayStr.append(temp1); } else { continue; } if(temp2.length()>0) { twoWordArrayStr.append(temp2); } else { twoWordArrayStr.append(lineArray[i+2].toLowerCase().trim()); } twoWordArrayStr.append("&"); }*/ // System.out.println(twoWordArrayStr.toString().trim()); String[] newlineArray = twoWordArrayStr.toString().trim().split("&"); for(String word:newlineArray) { word = word.toLowerCase().trim(); if(word.length()>0) if(index_map.containsKey(word)) { int value = index_map.get(word)+1; index_map.remove(word); index_map.put(word, value); } else { index_map.put(word, 1); } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } return index_map; }
排序算法:
public static List<Map.Entry<String,Integer>> sort(Map<String,Integer> source_data) { List<Map.Entry<String,Integer>> sort_data = new ArrayList<Map.Entry<String,Integer>>(source_data.entrySet()); Collections.sort(sort_data, new Comparator<Map.Entry<String,Integer>>() { @Override public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) { if(o1.getValue()!=null&&o2.getValue()!=null&&o2.getValue().compareTo(o1.getValue())>0) { return 1; } else { return -1; } } }); return sort_data; }