字典树

字典树

 

这个字典树还是比较简单的,首先记录下,为后面的AC自动机学习打下基础。

cnt是一个记录节点的编号,它开始的值是1。下面p = 0 是初始的值,其实就是root节点,这个root节点是空的,然后next【i】【j】中的i指的是第几个编号的结点,然后j指的是什么字符。

这里的exist【p】中p是每一个字符串的编号都是不一样的,为了避免absure这个单词干扰到abs是否存在这个情况,所以用exist来代表abs 是否存在。

 1 #include<iostream>
 2 #include<string>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn = 1000; 
 6 
 7 struct trie{
 8     int next[maxn][26]; //这里的是next[maxn][26],这里设置26是因为有26个小写字母 
 9     int cnt;
10     int exist[maxn];
11     
12     void insert(string str)//假设字符串是一个只有小写字母的情况下 
13     {
14         int len = str.size();
15         int p = 0;
16         for(int i = 0; i < len; i++)
17         {
18             int v = str[i]-'a';    //v是字母的值    
19             
20             if(!next[p][v])    
23                 next[p][v] = ++cnt;
24             p = next[p][v];
25         }
26         exist[p] = 1;//这里其实就是相当一个单词对应一个exist编号,如果存在就是1 
27         cout << p;
28     }
29     int find(string str)
30     {
31         int len = str.size();
32         int p = 0;
33         for(int i = 0; i < len; i++)
34         {
35             int v = str[i]-'a';
36             if(!next[p][v])    return 0;
37             else p = next[p][v];
38         }
39         return exist[p];        
40     }
41     void ini()
42     {
43         memset(exist, 0, sizeof(exist));
44         memset(next, 0, sizeof(next));
45         cnt = 1;
46     }
47 };
48 
49 int main()
50 {
51     struct trie root;
52     string str = "abs";
53     root.ini();
54     root.insert(str);
55     cout << root.find(str);
56 }

 

 来个板子题目熟悉下:

洛谷P2580 于是他错误的点名开始了:https://www.cnblogs.com/hyb-bbfss/p/13489778.html


 

 

在trie树中它经常使用的一个是进行异或操作。

它是这样的,将每个数字化成一个二进制数字,然后呢将每一位存到trie树中,其中高位在上,低位在下,由于这个性质,所以如果说是存int类型的,那么这个是一个32层的二叉树,开始root是空的,然后呢后面31层用来存数 ,从下开始衍生0和1。

可以上一个题目进行熟悉下:洛谷P4551 最长异或路径:https://www.cnblogs.com/hyb-bbfss/p/13496343.html

posted @ 2020-08-11 16:19  斌斌翻水水  阅读(174)  评论(0)    收藏  举报