Tire树集
Tire树:高效存储并查找字符串集合的数据结构

理解:Trie又被称为前缀树、字典树,所以当然是一棵树。上面这棵Trie树包含的字符串集合是{abc, adf, ,bcf}。每个节点的编号是我们为了描述方便加上去的。树中的每一条边上都标识有一个字符。这些字符可以是任意一个字符集中的字符。比如对于都是小写字母的字符串,字符集就是’a’-‘z’;对于都是数字的字符串,字符集就是’0’-‘9’;对于二进制字符串,字符集就是0和1。
比如上图中3号节点对应的路径0123上的字符串是abc,8号节点对应的路径678上的字符串是bcf。终结点与集合中的字符串是一一对应的。
具体来说,Trie一般支持两个操作:
- Trie.insert(W):第一个操作是插入操作,就是将一个字符串W加入到集合中。
- Trie.search(S):第二个操作是查询操作,就是查询一个字符串S是不是在集合中。
插入说明:在最初始的位置设置一个变量为p = 0;它表示的是起始的位置,if(!a[p][u])判断这个节点是否存在,倘若不存在那么我们就要创造一个节点:a[p][u] = ++idx; 创造了这个结点之后,将这个点的边表示为a,类似这种操作,持续插入abc。
查询说明:最简洁明了的方式就是判断走路线是否能够刚好走到最后一条,如果不能走到最后的节点路线或者是无路可走的状态,那么表示没有这个集。
例题:
第一行包含整数N,表示操作数。
接下来N行,每行包含一个操作指令,指令为”I x”或”Q x”中的一种。
对于每个询问指令”Q x”,都要输出一个整数作为结果,表示x在集合中出现的次数。
每个结果占一行。
#include<iostream>
using namespace std;
const int N = 10010;
//son记录所有的数据节点,con记录所有的集合,idx表示节点号
int son[N][26], con[N], idx;
char str[N];
//插入
void insert(char str[])
{
int p = 0;
for (int i = 0; str[i]; i++)
{
int u = str[i] - 'a';
if (!son[p][u]) son[p][u] = ++idx;
p = son[p][u];
}
con[p]++;
}
//查询
int query(char str[])
{
int p = 0;
for (int i = 0; str[i]; i++)
{
int u = str[i] - 'a';
if (!son[p][u])return 0;
p = son[p][u];
}
return con[p];
}
int main()
{
int n;
cin >> n;
while (n--)
{
char op[2];
cin >> op >> str;
if (op[0] == 'I')insert(str);
else cout << query(str) << endl;
}
return 0;
}
浙公网安备 33010602011771号