阅读英文文章时有时会出现不少这篇文章专有的一些单词,这些单词在其他地方不太可能会使用到,但是在阅读这篇文章时使用的频率可能会比较大,于是想能不能做一个工具,当你给定文章的url时,它将这篇文章中出现次数较多的那些单词统计出来。这样当你把这些单词的意义搞明白,再读这篇文章会不会压力小很多?
那么做这个工具的思路如下:
//Trie树节点数据结构 public class TrieNode { public int words;//以该节点结尾的单词数量 public int prefixs;//以该节点作为前缀的单词数量 public String str;//以该节点结尾的单词 public TrieNode[] edges;//该节点的子节点 public TrieNode() { this.words=0; this.prefixs=0; this.str=null; edges=new TrieNode[26]; for(int i=0;i<edges.length;i++) { edges[i]=null; } } }
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.PriorityQueue; import java.util.Queue; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Trie { private TrieNode root=new TrieNode(); private int count=10;//要显示的前count个单词 private int init;//这个初始值和count关联,用来向最小堆中插入初始的一些元素 //定义一个最小堆 private Queue<TrieNode> priorityQueue; //定义不需要统计的单词表 private Set<String> tables; //因为是要求出现次数最多的那些元素,所以使用最小堆 private Comparator<TrieNode> wordOrder=new Comparator<TrieNode>() { @Override public int compare(TrieNode o1, TrieNode o2) { // TODO Auto-generated method stub int word1=o1.words; int word2=o2.words; if (word1<word2) { return -1; } else if (word1>word2) { return 1; } else return 0; } }; public Trie() { // TODO Auto-generated constructor stub init=count; priorityQueue=new PriorityQueue<TrieNode>(count,wordOrder); //构建不需要统计的单词表 tables=new HashSet<String>(); String s = "[A-Za-z]+"; //下面列出不需要统计的单词 String words="a is an the h type c to of and or in for at"; Pattern pattern=Pattern.compile(s); Matcher ma=pattern.matcher(words); while(ma.find()){ tables.add(ma.group()); } } public void setCount(int c) { count=c; init=c; } //往Trie树种插入单词 public void insert(String word) { insertHelper(root, word); } //真正执行插入操作的函数 private void insertHelper(TrieNode node,String word) { if (word.length()==0) { node.words++; node.prefixs++; return; } node.prefixs++; char c=word.charAt(0); c=Character.toLowerCase(c); int index=c-'a'; if (node.edges[index]==null) { node.edges[index]=new TrieNode(); } insertHelper(node.edges[index], word.substring(1)); } public void traversal() { TrieNode[] edges=root.edges; for(int i=0;i<edges.length;i++) { if (edges[i]!=null) { String word=""+(char)('a'+i); depthTraversal(edges[i], word); } } } //对某一个节点执行深度优先的遍历 private void depthTraversal(TrieNode node,String wordPrefix) { if (node.words!=0) { node.str=wordPrefix; if (tables.contains(node.str)) { //如果该词在不需要统计的单词表中,不需要做任何处理 } else if(init>0) { init--; priorityQueue.add(node); } else { //如果大于最小堆的堆顶元素,那么将堆顶元素出队 if (node.words>priorityQueue.peek().words) { priorityQueue.poll(); priorityQueue.add(node); } } } TrieNode[] edges=node.edges; for(int i=0;i<edges.length;i++) { if (edges[i]!=null) { String newWord=wordPrefix+(char)('a'+i); depthTraversal(edges[i], newWord); } } } public List<TrieNode> getTrieNodes() { List<TrieNode> list=new ArrayList<TrieNode>(); //先将优先队列中的元素取出,然后进行排序 while (!priorityQueue.isEmpty()) { list.add(priorityQueue.poll()); } //执行降序排列 Collections.sort(list,new Comparator<TrieNode>() { @Override public int compare(TrieNode o1, TrieNode o2) { // TODO Auto-generated method stub if (o1.words<o2.words) { return 1; } else if(o1.words>o2.words){ return -1; } else { return 0; } } }); return list; } }
//根据网页的url将从网页抓取的单词插入tire树中 public static void getText3(String url,Trie trie) { Document doc; try { doc=Jsoup.connect(url).userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31").get(); String html=doc.text(); // System.out.println(html); String s = "[A-Za-z]+";//匹配单词,但是由英文大小写字母组成 // String s="\\w+"; Pattern pattern=Pattern.compile(s); Matcher ma=pattern.matcher(html); while(ma.find()){ // System.out.println(ma.group()); trie.insert(ma.group());//每次匹配一个单词,就将它插入Trie树中 } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
public static void main(String[] args) { // GUIFrame frame=new GUIFrame(); String url="http://www.cplusplus.com/reference/deque/deque/"; Trie trie=new Trie(); getText3(url, trie); trie.traversal(); List<TrieNode> list=trie.getTrieNodes(); //打印输出出现次数最多的那些字符串 for(TrieNode t:list) { System.out.println(t.str+" "+t.words); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u012501459/article/details/47752461