前兩天,寫了一個字典樹,感覺不太好,有點臃腫。
下面是根據網友的帖子(http://www.ej38.com/showinfo/java-184775.html,google搜索的,不曉得哪個是原創了),修改後的樣子。
package ruc.datasearch.trie;
import java.util.Iterator;
import java.util.List;
import ruc.datasearch.rule.Rule;
import ruc.datasearch.rule.Rules;
public class Trie {
private TrieNode root;
public Trie()
{
this.root=new TrieNode();
}
public Trie(Rules rs)
{
this.root=new TrieNode();
createTrieFromRules(rs);
}
public void createTrieFromRules(Rules rs)
{
Iterator<Rule> iter=rs.getRules().iterator();
try
{
while(iter.hasNext())
addRule(iter.next());
}
finally
{
iter=null;
}
}
public void addRule(Rule r)
{
boolean end, find;
TrieNode node=null;
try
{
node=this.root;
for(int i=0;i<r.lhs.length();i++)
{
find=false;
end=false;
List<TrieNode> trieLink=node.trieLink;
if(i==r.lhs.length()-1)
end=true;
//start to search matched character
char ch=r.lhs.charAt(i);
Iterator<TrieNode> iter=trieLink.iterator();
while(iter.hasNext())
{
node=iter.next();
if(node.c==ch)
{
find=true;
break;
}
}
//if not find, then create new node
if(!find)
{
TrieNode nodeTmp=new TrieNode(ch);
trieLink.add(nodeTmp);
node=nodeTmp;
}
//if end, then add rhs to target node
if(end&&!node.rhsList.contains(r.rhs))
node.rhsList.add(r.rhs);
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
node=null;
}
}
/**
* Search target list contained by target node
*
* @param lhs
* @return target lhs list, this lhs list could be empty
*/
public List<String> searchLhsReturnList(String lhs)
{
TrieNode node=searchLhsReturnNode(lhs);
if(node==null)
return null;
else
return node.rhsList;
}
/**
* Search target node
*
* @param lhs
* @return return target lhs node, this node could be null
*/
public TrieNode searchLhsReturnNode(String lhs)
{
boolean find,end;
TrieNode node=null;
try
{
node=root;
for(int i=0;i<lhs.length();i++)
{
find=false;
end=false;
if(i==lhs.length()-1)
end=true;
char ch=lhs.charAt(0);
List<TrieNode> trieLink=node.trieLink;
Iterator<TrieNode> iter=trieLink.iterator();
while(iter.hasNext())
{
node=iter.next();
if(node.c==ch)
{
find=true;
break;
}
}
if(!find)
{
node=null; //if node find character in any level,then return null
break;
}
if(end) //if this is the end level, return target node
break;
}
return node;
}
finally
{
node=null;
}
}
}
package ruc.datasearch.trie;
import java.util.LinkedList;
import java.util.List;
public class TrieNode {
public char c;
public LinkedList<TrieNode> trieLink;
public List<String> rhsList;
public TrieNode()
{
this.trieLink=new LinkedList<TrieNode>();
}
public TrieNode(char c)
{
this.c=c;
this.trieLink=new LinkedList<TrieNode>();
}
}