字典树
字典树

这个字典树还是比较简单的,首先记录下,为后面的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

浙公网安备 33010602011771号