阅读英文文章时有时会出现不少这篇文章专有的一些单词,这些单词在其他地方不太可能会使用到,但是在阅读这篇文章时使用的频率可能会比较大,于是想能不能做一个工具,当你给定文章的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