Add convenience methods to PrefixTree + add SimpleCharPrefixTree.

This commit is contained in:
asofold 2012-09-03 10:19:57 +02:00
parent 27a74a4cfb
commit 4144e14bac
2 changed files with 202 additions and 1 deletions

View File

@ -84,10 +84,40 @@ public class PrefixTree<K, N extends Node<K>, L extends LookupEntry<K, N>>{
this.resultFactory = resultFactory;
}
public LookupEntry<K, N> lookup(K[] keys, final boolean create){
/**
* Look up without creating new nodes.
* @param keys
* @return
*/
public L lookup(final K[] keys){
return lookup( keys, false);
}
/**
* Look up without creating new nodes.
* @param keys
* @return
*/
public L lookup(final List<K> keys){
return lookup( keys, false);
}
/**
* Look up sequence, if desired fill in the given sequence.
* @param keys
* @param create
* @return
*/
public L lookup(K[] keys, final boolean create){
return lookup(Arrays.asList(keys), create);
}
/**
* Look up sequence, if desired fill in the given sequence.
* @param keys
* @param create
* @return
*/
@SuppressWarnings("unchecked")
public L lookup(final List<K> keys, final boolean create){
N insertion = root;
@ -121,6 +151,80 @@ public class PrefixTree<K, N extends Node<K>, L extends LookupEntry<K, N>>{
}
return resultFactory.newLookupEntry(node, insertion, depth, hasPrefix);
}
/**
*
* @param keys
* @return If already inside (not necessarily as former end point).
*/
public boolean feed(final List<K> keys){
final L result = lookup(keys, true);
return result.insertion == result.node;
}
/**
*
* @param chars
* @return If already inside (not necessarily as former end point).
*/
public boolean feed(final K[] keys){
return feed(Arrays.asList(keys));
}
/**
* Check if the tree has a prefix of keys. This does not mean a common prefix, but that the tree contains an end point that is a prefix of the input.
* @param keys
* @return
*/
public boolean hasPrefix(final List<K> keys){
return lookup(keys, false).hasPrefix;
}
/**
* Check if the tree has a prefix of keys. This does not mean a common prefix, but that the tree contains an end point that is a prefix of the input.
* @param keys
* @return
*/
public boolean hasPrefix(final K[] keys){
return hasPrefix(Arrays.asList(keys));
}
/**
* Check if the input is prefix of a path inside of the tree, need not be an end point.
* @param keys
* @return
*/
public boolean isPrefix(final List<K> keys){
return lookup(keys, false).depth == keys.size();
}
/**
* Check if the input is prefix of a path inside of the tree, need not be an end point.
* @param keys
* @return
*/
public boolean isPrefix(final K[] keys){
return isPrefix(Arrays.asList(keys));
}
/**
* Check if the input is an inserted sequence (end point), but not necessarily a leaf.
* @param keys
* @return
*/
public boolean matches(final List<K> keys){
final L result = lookup(keys, false);
return result.node == result.insertion && result.insertion.isEnd;
}
/**
* Check if the input is an inserted sequence (end point), but not necessarily a leaf.
* @param keys
* @return
*/
public boolean matches(final K[] keys){
return matches(Arrays.asList(keys));
}
public void clear() {
root = nodeFactory.newNode(null);

View File

@ -0,0 +1,97 @@
package fr.neatmonster.nocheatplus.checks.chat.analysis.ds;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Adding some convenience methods.
* @author mc_dev
*
*/
public class SimpleCharPrefixTree extends SimplePrefixTree<Character>{
/**
* Auxiliary method to get a List of Character.
* @param chars
* @return
*/
public static final List<Character> toCharacterList(final char[] chars){
final List<Character> characters = new ArrayList<Character>(chars.length);
for (int i = 0; i < chars.length; i++){
characters.add(chars[i]);
}
return characters;
}
/**
*
* @param chars
* @param create
* @return
*/
public SimpleLookupEntry<Character> lookup(final char[] chars, boolean create){
return lookup(toCharacterList(chars), create);
}
/**
*
* @param chars
* @param create
* @return
*/
public SimpleLookupEntry<Character> lookup(final String input, boolean create){
return lookup(input.toCharArray(), create);
}
/**
*
* @param chars
* @return If already inside (not necessarily as former end point).
*/
public boolean feed(final String input){
return feed(input.toCharArray());
}
/**
*
* @param chars
* @return If already inside (not necessarily as former end point).
*/
public boolean feed(final char[] chars){
return feed(toCharacterList(chars));
}
public void feedAll(final Collection<String> inputs, boolean trim, boolean lowerCase){
for (String input : inputs){
if (trim) input = input.toLowerCase();
if (lowerCase) input = input.toLowerCase();
feed(input);
}
}
public boolean hasPrefix(final char[] chars){
return hasPrefix(toCharacterList(chars));
}
public boolean hasPrefix(final String input){
return hasPrefix(input.toCharArray());
}
public boolean isPrefix(final char[] chars){
return isPrefix(toCharacterList(chars));
}
public boolean isPrefix(final String input){
return isPrefix(input.toCharArray());
}
public boolean matches(final char[] chars){
return matches(toCharacterList(chars));
}
public boolean matches(final String input){
return matches(input.toCharArray());
}
}