字典树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
思路:每加入一个单词后,列如单词‘abcd’,首先会在根结点出查找是否有字母a,如果没有,创建一个节点,并给节点一个编号,表示这是第i个插入的节点,接着以字母a这个节点为根结点,查找是否有'b'这个子节点,没有则创建节点,并给节点一个编号,表示这是第i+1个节点。再次检查以'b'节点为根结点是否有子节点‘c’,没有则创建,并给节点一个编号,表示这是第i+2个节点,再次检查以‘c’为根结点是否有子节点'd',如果没有则创建,并给节点一个编号。最后单词'abcd'创建成功。统计以该节点结尾的单词数 + 1.
描述:son[i][j] = ++index i表示父节点的编号,j表示字母(大小写都可以),index表示插入的节点序号
字典树的基本操作:查询和插入操作
static int N = 100010;
static int[][] son = new int[N][26]; // 用于表示节点,二维个数26表示可以有26个子节点
static int[] cnt = new int[N]; //cnt[i] 表示在第i个节点结尾的单词有xxx个
static int index = 0; // 用于表示第xx个节点
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
Integer n = Integer.parseInt(bf.readLine());
while(n -- > 0) {
String[] s = bf.readLine().split(" ");
char[] ch = s[1].toCharArray();
if(s[0].equals("I")) {
insert(ch);
} else{
// System.out.println(query(ch));
bw.write(query(ch) + " ");
}
}
bw.flush();
bw.close();
bf.close();
}
public static int query(char[] ch) {
int p = 0;
for (int i = 0; i < ch.length; i ++) {
int u = ch[i] - 'a';
if(son[p][u] == 0) return 0;
p = son[p][u];
}
return cnt[p];
}
public static void insert(char[] ch) {
int p = 0;
for (int i = 0; i < ch.length; i ++) {
int u = ch[i] - 'a';
if(son[p][u] == 0) son[p][u] = ++index;
p = son[p][u];
}
cnt[p]++;
}