import java.util.HashMap;

/**
* 前缀树
* 又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。
* 典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。
* 它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高
*/
public class TrieTest {

/**
* 多叉树
*/
public static class Node {

public int pass;

public int end;

public HashMap<Integer, Node> nexts;

public Node() {
nexts = new HashMap<>();
}

}

/**
* 前缀树
*/
public static class Trie {

public Node root;

public Trie() {
root = new Node();
}

/**
* 往树中加入一个字符串
*
* @param value 加入的值
*/
public void insert(String value) {
if (value == null) {
return;
}
int ars = 0;
Node node = root;
node.pass++;
char[] chars = value.toCharArray();
for (int i = 0; i < chars.length; i++) {
ars = (int) chars[i];
if (!node.nexts.containsKey(ars)) {
node.nexts.put(ars, new Node());
}
node = node.nexts.get(ars);
node.pass++;
}
node.end++;
}

/**
* 查找value字符串被加入了几次
*
* @param value 字符串
* @return 加入次数
*/
public int search(String value) {
if (value == null) {
return 0;
}
int ars = 0;
Node node = root;
char[] chars = value.toCharArray();
for (int i = 0; i < chars.length; i++) {
ars = (int) chars[i];
if (!node.nexts.containsKey(ars)) {
return 0;
}
node = node.nexts.get(ars);
}
return node.end;
}

/**
* 删除指定字符串(如果存在)
*
* @param value 字符串
*/
public void delete(String value) {
if (search(value) == 0) {
return;
}
int ars = 0;
Node node = root;
node.pass--;
char[] chars = value.toCharArray();
for (int i = 0; i < chars.length; i++) {
ars = (int) chars[i];
if (--node.nexts.get(ars).pass == 0) {
node.nexts.remove(ars);
return;
}
node = node.nexts.get(ars);
}
node.end--;
}

/**
* 求所有字符串中,以pre为前缀的字符串个数
*
* @param pre 前缀
* @return 个数
*/
public int prefixNum(String pre) {
if (pre == null) {
return 0;
}
int ars = 0;
Node node = root;
char[] chars = pre.toCharArray();
for (int i = 0; i < chars.length; i++) {
ars = (int) chars[i];
if (!node.nexts.containsKey(ars)) {
return 0;
}
node = node.nexts.get(ars);
}
return node.pass;
}

}

}

/* 如有意见或建议,欢迎评论区留言;如发现代码有误,欢迎批评指正 */