import java.util.*;
public class Solution {
public class TrieNode {
public int pre;
public int end;
public TrieNode[] paths;
public TrieNode() {
pre = 0;
end = 0;
paths = new TrieNode[26];
}
}
public class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
// 添加 word,可重复添加
public void insert(String word) {
if (null == word) {
return;
}
char[] chrs = word.toCharArray();
TrieNode node = root;
node.pre++;
int index = 0;
for (int i = 0; i < chrs.length; i++) {
index = chrs[i] - 'a';
if (null == node.paths[index]) {
node.paths[index] = new TrieNode();
}
node = node.paths[index];
node.pre++;
}
node.end++;
}
// 删除 word,如果 word 添加过多次,仅删除一次
public void delete (String word) {
if (search(word)) {
char[] chrs = word.toCharArray();
TrieNode node = root;
node.pre--;
int index = 0;
for (int i = 0; i < chrs.length; i++) {
index = chrs[i] - 'a';
if (--node.paths[index].pre == 0) {
node.paths[index] = null;
return;
}
node = node.paths[index];
}
node.end--;
}
}
// 查询 word 是否在字典树中出现过(完整的出现过,前缀式不算)
public boolean search(String word) {
if (null == word) {
return false;
}
char[] chrs = word.toCharArray();
TrieNode node = root;
int index = 0;
for (int i = 0; i < chrs.length; i++) {
index = chrs[i] - 'a';
if (null == node.paths[index]) {
return false;
}
node = node.paths[index];
}
return node.end > 0 ? true : false;
}
// 返回以字符串 pre 作为前缀的单词数量
public int prefixNumber(String pre) {
if (null == pre) {
return 0;
}
char[] chrs = pre.toCharArray();
TrieNode node = root;
int index = 0;
for (int i = 0; i < chrs.length; i++) {
index = chrs[i] - 'a';
if (null == node.paths[index]) {
return 0;
}
node = node.paths[index];
}
return node.pre;
}
}
/**
*
* @param operators string字符串二维数组 the ops
* @return string字符串一维数组
*/
public String[] trieU (String[][] operators) {
// write code here
if (0 == operators.length) {
return new String[] {};
}
Trie trie = new Trie();
ArrayList<String> rs = new ArrayList<>();
for (String[] operator : operators) {
int op = Integer.valueOf(operator[0]);
String str = operator[1];
switch (op) {
case 1:
trie.insert(str);
break;
case 2:
trie.delete(str);
break;
case 3 :
boolean bool = trie.search(str);
if (bool) {
rs.add("YES");
} else {
rs.add("NO");
}
break;
default:
int num = trie.prefixNumber(str);
rs.add(String.valueOf(num));
}
}
String[] strs = new String[rs.size()];
for (int i = 0; i < strs.length; i++) {
strs[i] = rs.get(i);
}
return strs;
}
}