详细的解答这里不再赘述,推荐两篇博文,
https://www.cnblogs.com/hyfhaha/p/10802604.html;
https://blog.csdn.net/wyxeainn/article/details/77430218?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-6&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-6;
这里略微分析一下我对前缀数组的认识和性质
//定理 1:对于每一条树链如果fial[level1[k1]]=fial[level2[k2]],k1<k2,则存在0~k1,fial[level[i]]=fial[level2[k2-k1+i]]总成立
//性质2:fail路径直达定理,如果fail[level]指向的是一个本来不存在的地址,trie[][i]存在可能最大的地址;
//匹配失败:如果文章匹配到某一条树链的level[t],下一个要查询的是index+'a,然而trie[level[t]][index]不存在我们就定义失败,扫描的指针指向fail
// fail 指针的作用:当前的树链是否可能是别的树链答案,已经是别的树链的答案。我们通过fail遍历所有以当前字母结尾的前缀中是否有答案;
1 #include<iostream> 2 #include<string> 3 #include<queue> 4 #include<cstring> 5 using namespace std; 6 const int MAX_=1e5; 7 int trie[MAX_][26]={0}; 8 int wordti[MAX_]={0};//功能数组; 9 int fail[MAX_]={0}; 10 int cnt=0; 11 void insert(string x) 12 { 13 int len=x.size(),p=0; 14 for(int i=0;i<len;i++) 15 { 16 int index=x[i]-'a'; 17 if(trie[p][index]!=0) 18 trie[p][index]=++cnt; 19 p=trie[p][index]; 20 } 21 wordti[p]++; 22 } 23 //定理 1:对于每一条树链如果fial[level1[k1]]=fial[level2[k2]],k1<k2,则存在0~k1,fial[level[i]]=fial[level2[k2-k1+i]]总成立 24 //性质2:fail路径直达定理,如果fail[level]指向的是一个本来不存在的地址,trie[][i]存在可能最大的地址; 25 //匹配失败:如果文章匹配到某一条树链的level[t],下一个要查询的是index+'a,然而trie[level[t]][index]不存在我们就定义失败,扫描的指针指向fail 26 // fail 指针的作用:当前的树链是否可能是别的树链答案,已经是别的树链的答案。我们通过fail遍历所有以当前字母结尾的前缀中是否有答案; 27 void getfail() 28 { 29 queue<int >que; 30 for(int i=0;i<26;i++) 31 if(trie[0][i]!=0){ 32 fail[trie[0][i]]=0; 33 que.push(trie[0][i]); 34 } 35 while(!que.empty()){ 36 int now=que.front(); 37 que.pop(); 38 for(int i=0;i<26;i++){ 39 if(trie[now][i]!=0){ 40 fail[trie[now][i]]=trie[fail[now]][i];//祖先继承法;特征我们数通过记忆化搜索,或者等于它已经记录的数据实现的 41 que.push(trie[now][i]); 42 } 43 else 44 trie[now][i]=trie[fail[now]][i];//我们只要研究如果当前节点存在,就往下搜索,如果这个指针不存在,我们通过fail直接到达可行的下表 45 } 46 } 47 } 48 49 void query(char *s) 50 { 51 int u=0,len=strlen(s); 52 for(int i=0;i<len;i++){ 53 int index=s[i]-'a'; 54 u=trie[u][index]; 55 //功能区 ,寻找以当前字母结尾是否存在已经匹配成功的模式窜 56 int k=u; 57 while(k>0){ 58 if(wordti[k]>0) ans++; 59 k=fail[k]; 60 } 61 } 62 }