trie树
主要用途:快速存储字符串集合的数据结构。
问题描述
需要两个数组一个用于存储当前位置的下一个结点的坐标,一个用于存储当前位置是否是一个字符串的结尾。
维护一个字符串集合,支持两种操作:
“I x”向集合中插入一个字符串x;
“Q x”询问一个字符串在集合中出现了多少次。
共有N个操作,输入的字符串总长度不超过 105,字符串仅包含小写英文字母。
输入格式
第一行包含整数N,表示操作数。
接下来N行,每行包含一个操作指令,指令为”I x”或”Q x”中的一种。
输出格式
对于每个询问指令”Q x”,都要输出一个整数作为结果,表示x在集合中出现的次数。
每个结果占一行。
数据范围
1≤N≤2∗104
输入样例:
5
I abc
Q abc
Q ab
I ab
Q ab
输出样例:
1
0
1
代码
#include<iostream>
using namespace std;
int trie[20010][26], idx = 0, flag[20010];
void insert(char *s){
int q = 0;
for(int i = 0; s[i]; ++i){
int x = s[i] - 'a';
if(!trie[q][x])trie[q][x] = ++idx; // 如果当前位置的为空说明没有这个字节点,需要创建一个
q = trie[q][x];
}
flag[q]++;
}
void query(char *s){
int q = 0;
for(int i = 0; s[i]; ++i){
int x= s[i] - 'a';
if(!trie[q][x]) {cout << "0" << endl;return;}
q = trie[q][x];
}
cout << flag[q] << endl;
}
int main(){
int n;
cin >> n;
for(int i = 0; i < n; ++i){
char m;
char x[20010];
cin >> m >> x;
if(m == 'I') insert(x);
if(m == 'Q') query(x);
}
return 0;
}