com.davidthomasbernal.stardict.util.datastructures.TrieMap Maven / Gradle / Ivy
package com.davidthomasbernal.stardict.util.datastructures;
import javax.naming.OperationNotSupportedException;
import java.util.*;
/**
* Created by david on 4/5/15.
*/
public class TrieMap extends AbstractMap{
protected static class TreeNode {
HashMap> nodes = new HashMap<>();
T data;
}
TreeNode root = new TreeNode<>();
public final char EOW = Character.MAX_VALUE;
protected char[] getWordChars(String word) {
char[] chars = Arrays.copyOf(word.toCharArray(), word.length() + 1);
chars[word.length()] = EOW;
return chars;
}
@Override
public T get(Object key) {
return get((String)key);
}
public T get(String word) {
char[] chars = getWordChars(word);
TreeNode node = findNode(chars);
if (node == null) {
return null;
}
return node.data;
}
@Override
public boolean containsKey(Object key) {
return containsKey((String)key);
}
public boolean containsKey(String word) {
TreeNode node = root;
char[] chars = getWordChars(word);
for (Character charr : chars) {
if (!node.nodes.containsKey(charr)) {
return false;
}
node = node.nodes.get(charr);
}
return true;
}
protected TreeNode findNode(char [] chars) {
TreeNode node = root;
for (char charr : chars) {
if (!node.nodes.containsKey(charr)) {
return null;
}
node = node.nodes.get(charr);
}
return node;
}
public List prefixSearch(String prefix) {
char [] chars = prefix.toCharArray();
TreeNode node = findNode(chars);
if (node == null) {
return Collections.emptyList();
}
Set> wordEntries = searchFrom(node, new StringBuilder(prefix));
List result = new ArrayList(wordEntries.size());
for (Entry wordEntry : wordEntries) {
result.add(wordEntry.getKey());
}
return result;
}
protected Set> searchFrom(TreeNode node, StringBuilder prefix) {
Set> words = new HashSet<>();
for (Map.Entry> entry : node.nodes.entrySet()) {
if (entry.getKey() == EOW) {
Entry result = new SimpleImmutableEntry(prefix.toString(), entry.getValue().data);
words.add(result);
} else {
StringBuilder newPrefix = new StringBuilder(prefix);
newPrefix.append(entry.getKey());
words.addAll(searchFrom(entry.getValue(), newPrefix));
}
}
return words;
}
@Override
public Set> entrySet() {
Set> entries = searchFrom(root, new StringBuilder(""));
return entries;
}
@Override
public T put(String word, T data) {
TreeNode node = root;
char[] chars = getWordChars(word);
for (Character charr : chars) {
if (!node.nodes.containsKey(charr)) {
node.nodes.put(charr, new TreeNode());
}
node = node.nodes.get(charr);
}
T prevData = null;
if (node.data != null) {
prevData = node.data;
}
node.data = data;
return prevData;
}
@Override
public T remove(Object key) {
throw new UnsupportedOperationException();
}
}