Skip to content

Instantly share code, notes, and snippets.

Created February 10, 2011 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/821393 to your computer and use it in GitHub Desktop.
Save anonymous/821393 to your computer and use it in GitHub Desktop.
a Trie class and it's supporting class TrieNode
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);
}
}
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