标签:
推荐博客
http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html
模板使用的是LRJ的,这里使用了last数组,并没有补边。
last数组的含义:当你遍历到目标串T的c节点时,T[1,c]的后缀可能是模板串.所以记录下来
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long #define CLR(x) memset(x,0,sizeof x) #define MC(x,y) memcpy(x,y,sizeof(x)) #define SZ(x) ((int)(x).size()) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define INF 1e18 typedef pair<int,int> P; const double eps=1e-9; const int maxnnode=11000; const int maxn=150+10; const int mod=20071027; struct AhoCorasickAutomata{ int ch[maxnnode][26]; int f[maxnnode]; int val[maxnnode]; int last[maxnnode]; int cnt[maxn]; int sz; void Init(){ sz=1; CLR(ch);CLR(cnt); } int Idx(char c){return c-‘a‘;}//将模板插入Trie中 void Insert(char *s,int v){ int u=0,n=strlen(s); for(int i=0;i<n;i++){ int c=Idx(s[i]); if(!ch[u][c]) { CLR(ch[sz]); val[sz]=0; ch[u][c]=sz++; } u=ch[u][c]; } val[u]=v; } void Print(int j){ if(j){ printf("%d %d\n",j,val[j]); Print(last[j]); } } void Find(char* T){ int n=strlen(T); int j=0; for(int i=0;i<n;i++){ int c=Idx(T[i]); while(j&&!ch[j][c]) j=f[j]; j=ch[j][c]; if(val[j]) Print(j); else if(last[j]) Print(last[j]); } } void Getfail(){ queue<int> q; f[0]=0; for(int c=0;c<26;c++){ int u=ch[0][c]; if(u){f[u]=0;q.push(u);last[u]=0;} } while(!q.empty()){ int r=q.front();q.pop(); for(int c=0;c<26;c++){ int u=ch[r][c]; if(!u) continue; q.push(u); int v=f[r]; while(v&&!ch[v][c]) v=f[v]; f[u]=ch[v][c]; last[u]=val[f[u]]?f[u]:last[f[u]]; } } } }; AhoCorasickAutomata ac; char tmp[maxn]; int main(){ int n; scanf("%d",&n); ac.Init(); for(int i=1;i<=n;i++){ scanf("%s",tmp); ac.Insert(tmp,i); } ac.Getfail(); scanf("%s",tmp); ac.Find(tmp); return 0; } /* 样例 5 one two three four five oneoneonetwotwotwofourfffffiveffadfafdathree */
标签:
原文地址:http://www.cnblogs.com/byene/p/5797840.html