作者 crossoverJie

:sparkles: Introducing new features.字典树

package com.crossoverjie.cim.common.data.construct;
import com.crossoverjie.cim.common.util.StringUtil;
import java.util.ArrayList;
import java.util.List;
/**
* Function:
* Function:字典树字符前缀模糊匹配
*
* @author crossoverJie
* Date: 2019/1/7 18:58
... ... @@ -9,33 +14,198 @@ package com.crossoverjie.cim.common.data.construct;
*/
public class TrieTree {
private Node root ;
private static final int CHILDREN_LENGTH = 26 * 2;
private static final int MAX_CHAR_LENGTH = 16;
private static final char UPPERCASE_STAR = 'A';
/**
* 小写就要 -71
*/
private static final char LOWERCASE_STAR = 'G';
private Node root;
public TrieTree() {
root = new Node(null);
root = new Node();
}
/**
* 写入
*
* @param data
*/
public void insert(String data) {
this.insert(this.root, data);
}
public void insert(String data){
private void insert(Node root, String data) {
char[] chars = data.toCharArray();
for (char aChar : chars) {
for (int i = 0; i < chars.length; i++) {
char aChar = chars[i];
int index ;
if (Character.isUpperCase(aChar)) {
index = aChar - UPPERCASE_STAR;
} else {
//小写就要 -71
index = aChar - LOWERCASE_STAR;
}
if (index >= 0 && index < CHILDREN_LENGTH) {
if (root.children[index] == null) {
Node node = new Node();
root.children[index] = node;
root.children[index].data = chars[i];
}
//最后一个字符设置标志
if (i + 1 == chars.length) {
root.children[index].isEnd = true;
}
//指向下一节点
root = root.children[index];
}
}
}
/**
* 递归深度遍历
*
* @param key
* @return
*/
public List<String> prefixSearch(String key) {
List<String> value = new ArrayList<String>();
if (StringUtil.isEmpty(key)) {
return value;
}
char k = key.charAt(0);
int index;
if (Character.isUpperCase(k)) {
index = k - UPPERCASE_STAR;
} else {
index = k - LOWERCASE_STAR;
}
if (root.children != null && root.children[index] != null) {
return query(root.children[index], value,
key.substring(1), String.valueOf(k));
}
return value;
}
private List<String> query(Node child, List<String> value, String key, String result) {
if (child.isEnd && key == null) {
value.add(result);
}
if (key != null) {
char ca = key.charAt(0);
int index;
if (Character.isUpperCase(ca)) {
index = ca - UPPERCASE_STAR;
} else {
index = ca - LOWERCASE_STAR;
}
if (child.children[index] != null) {
query(child.children[index], value, key.substring(1).equals("") ? null : key.substring(1), result + ca);
}
} else {
for (int i = 0; i < CHILDREN_LENGTH; i++) {
if (child.children[i] != null) {
int j;
if (Character.isUpperCase(child.children[i].data)) {
j = UPPERCASE_STAR + i;
} else {
j = LOWERCASE_STAR + i;
}
char temp = (char) j;
query(child.children[i], value, null, result + temp);
}
}
}
return value;
}
/**
* 查询所有
*
* @return
*/
public List<String> all() {
char[] chars = new char[MAX_CHAR_LENGTH];
List<String> value = depth(this.root, new ArrayList<String>(), chars, 0);
return value;
}
private class Node{
private Node left ;
private Node right ;
private Character data ;
public Node(Character data) {
this.data = data;
public List<String> depth(Node node, List<String> list, char[] chars, int index) {
if (node.children == null || node.children.length == 0) {
return list;
}
public Node(Node left, Node right, Character data) {
this.left = left;
this.right = right;
this.data = data;
Node[] children = node.children;
for (int i = 0; i < children.length; i++) {
Node child = children[i];
if (child == null) {
continue;
}
if (child.isEnd) {
chars[index] = child.data;
char[] temp = new char[index + 1];
for (int j = 0; j < chars.length; j++) {
if (chars[j] == 0) {
continue;
}
temp[j] = chars[j];
}
list.add(String.valueOf(temp));
return list;
} else {
chars[index] = child.data;
index++;
depth(child, list, chars, index);
index = 0;
}
}
return list;
}
private class Node {
/**
* 是否为最后一个字符
*/
public boolean isEnd = false;
/**
* 如果支持查询,则不需要存储数据
*/
public char data;
public Node[] children = new Node[CHILDREN_LENGTH];
}
}
... ...
package com.crossoverjie.cim.common.data.construct;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TrieTreeTest {
@Test
public void insert() throws Exception {
TrieTree trieTree = new TrieTree();
trieTree.insert("abc");
trieTree.insert("abcd");
}
@Test
public void all() throws Exception {
TrieTree trieTree = new TrieTree();
trieTree.insert("ABC");
trieTree.insert("abC");
List<String> all = trieTree.all();
for (String s : all) {
System.out.println(s);
}
}
@Test
public void prefixSearch() throws Exception {
TrieTree trieTree = new TrieTree();
trieTree.insert("abc");
trieTree.insert("abd");
trieTree.insert("ABe");
List<String> ab = trieTree.prefixSearch("AB");
for (String s : ab) {
System.out.println(s);
}
System.out.println("========");
//char[] chars = new char[3] ;
//for (int i = 0; i < 3; i++) {
// int a = 97 + i ;
// chars[i] = (char) a ;
//}
//
//String s = String.valueOf(chars);
//System.out.println(s);
}
@Test
public void prefixSearch2() throws Exception {
TrieTree trieTree = new TrieTree();
trieTree.insert("Cde");
trieTree.insert("CDa");
trieTree.insert("ABe");
List<String> ab = trieTree.prefixSearch("AC");
for (String s : ab) {
System.out.println(s);
}
Assert.assertTrue(ab.size() == 0);
}
@Test
public void prefixSearch3() throws Exception {
TrieTree trieTree = new TrieTree();
trieTree.insert("Cde");
trieTree.insert("CDa");
trieTree.insert("ABe");
List<String> ab = trieTree.prefixSearch("CD");
for (String s : ab) {
System.out.println(s);
}
Assert.assertTrue(ab.size() == 1);
}
@Test
public void prefixSearch4() throws Exception {
TrieTree trieTree = new TrieTree();
trieTree.insert("Cde");
trieTree.insert("CDa");
trieTree.insert("ABe");
List<String> ab = trieTree.prefixSearch("Cd");
String result = "";
for (String s : ab) {
result += s + "," ;
System.out.println(s);
}
Assert.assertTrue(result.equals("Cde,"));
}
@Test
public void prefixSearch5() throws Exception {
TrieTree trieTree = new TrieTree();
trieTree.insert("Cde");
trieTree.insert("CDa");
trieTree.insert("ABe");
trieTree.insert("CDfff");
trieTree.insert("Cdfff");
List<String> ab = trieTree.prefixSearch("Cd");
String result = "";
for (String s : ab) {
result += s + "," ;
System.out.println(s);
}
Assert.assertTrue(result.equals("Cde,Cdfff,"));
}
@Test
public void prefixSearch6() throws Exception {
TrieTree trieTree = new TrieTree();
trieTree.insert("Cde");
trieTree.insert("CDa");
trieTree.insert("ABe");
trieTree.insert("CDfff");
trieTree.insert("Cdfff");
List<String> ab = trieTree.prefixSearch("CD");
String result = "";
for (String s : ab) {
result += s + "," ;
System.out.println(s);
}
Assert.assertTrue(result.equals("CDa,CDfff,"));
}
}
\ No newline at end of file
... ...