Created
February 10, 2011 21:33
-
-
Save anonymous/821393 to your computer and use it in GitHub Desktop.
a Trie class and it's supporting class TrieNode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package local.tree.trie; | |
import java.util.LinkedList; | |
import java.util.List; | |
public final class Trie { | |
private final TrieNode root; | |
public Trie() { | |
root = new TrieNode(null, '*'); | |
} | |
/** | |
* Add a new word to the Trie | |
* @param s the word to add | |
* @return a TrieNode reference to the word | |
*/ | |
public TrieNode addWord(String s) { | |
return root.addChild(s.toLowerCase()); | |
} | |
/** | |
* Return the word the provided TrieNode represents | |
* @param node the TrieNode | |
* @return //TODO | |
*/ | |
public String getWord(TrieNode node) { | |
return node.getWord(new StringBuffer()).reverse().toString(); | |
} | |
/** | |
* Suggest a list of words for the given string | |
* @param s provided word or part of word | |
* @return all suggestions available in the Trie, an empty list of no word was found | |
*/ | |
public List<String> suggest(String s) { | |
List<String> words = new LinkedList<String>(); | |
// Navigate the Trie to reach the TrieNode matching the string | |
TrieNode last = search(s.toLowerCase()); | |
if (last == root || last == null) { | |
return words; | |
} else { | |
List<TrieNode> tnodes = last.getTree(new LinkedList<TrieNode>()); | |
for (TrieNode n : tnodes) { | |
words.add(this.getWord(n)); | |
} | |
} | |
return words; | |
} | |
/* | |
* Return the TrieNode best matching the provided string | |
*/ | |
private TrieNode search(String s) { | |
return root.find(s); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package local.tree.trie; | |
import java.util.ArrayList; | |
import java.util.List; | |
final class TrieNode { | |
private final char label; | |
private final TrieNode parent; | |
private boolean isword = false; | |
private List<TrieNode> children; | |
TrieNode(TrieNode par, char c) { | |
label = c; | |
parent = par; | |
} | |
private TrieNode getParent() { | |
return parent; | |
} | |
private char getLabel() { | |
return label; | |
} | |
private TrieNode hasChild(char c) { | |
for (TrieNode node : children) { | |
if (node.getLabel() == c) | |
return node; | |
} | |
return null; | |
} | |
/** | |
* Return the word for the given TrieNode | |
* @param sb String buffer to modify | |
* @return a modified String buffer (reverse order) | |
*/ | |
StringBuffer getWord(StringBuffer sb) { | |
TrieNode node = this; | |
while (node.getParent() != null) { | |
sb.append(node.getLabel()); | |
node = node.getParent(); | |
} | |
return sb; | |
} | |
/** | |
* Add a new String among the TrieNodes | |
* @param s the word | |
* @return the TrieNode referencing the added word | |
*/ | |
TrieNode addChild(String s) { | |
if (s.length() < 1) { // base case | |
isword = true; | |
return this; | |
} | |
if (children == null) // init if neccessary | |
children = new ArrayList<TrieNode>(); | |
TrieNode nn = hasChild(s.charAt(0)); | |
if (nn == null) { | |
nn = new TrieNode(this, s.charAt(0)); | |
children.add(nn); | |
} | |
return nn.addChild(s.substring(1)); // recursion | |
} | |
/** | |
* Locate the appropriate TrieNode for the given String | |
* @param s the word | |
* @return a TrieNode if there is a match, null if no word is found | |
*/ | |
TrieNode find(String s) { | |
if (s.length() > 0) { | |
TrieNode n = hasChild(s.charAt(0)); | |
if (n != null) { | |
return n.find(s.substring(1)); | |
} else { | |
return null; // no word found | |
} | |
} | |
return this; // this is the word | |
} | |
/** | |
* populate the provided list with all siblings of this TrieNode | |
* @param list to put the TrieNodes in | |
* @return a List with TrieNodes, empty if no nodes were found | |
*/ | |
List<TrieNode> getTree(List<TrieNode> list) { | |
if (children != null) { | |
for (TrieNode n : children) { | |
if (n.isword) | |
list.add(n); // only want whole words | |
n.getTree(list); | |
} | |
} | |
return list; // if there are no children | |
} | |
@Override | |
public String toString() { | |
return String.valueOf(getLabel()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment