panda_1

Tire树集

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

理解:Trie又被称为前缀树、字典树,所以当然是一棵树。上面这棵Trie树包含的字符串集合是{abc, adf, ,bcf}。每个节点的编号是我们为了描述方便加上去的。树中的每一条边上都标识有一个字符。这些字符可以是任意一个字符集中的字符。比如对于都是小写字母的字符串,字符集就是’a’-‘z’;对于都是数字的字符串,字符集就是’0’-‘9’;对于二进制字符串,字符集就是0和1。

比如上图中3号节点对应的路径0123上的字符串是abc,8号节点对应的路径678上的字符串是bcf。终结点与集合中的字符串是一一对应的。

具体来说,Trie一般支持两个操作:

  1. Trie.insert(W):第一个操作是插入操作,就是将一个字符串W加入到集合中。
  2. 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;
}

posted on 2021-02-28 15:15  panda_1  阅读(60)  评论(0)    收藏  举报

导航