AC 自动机
AC 自动机可以用来处理多模式匹配,AC 自动机是以 TRIE 的结构为基础 ,结合 KMP 的思想 建立的。
** 具体步骤 **
1.构建 Trie
2.构建失配指针
3.进行多模式匹配
例题 洛谷3808 AC自动机(简单版)
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; int read() { int k=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) k=k*10+c-'0';return k*f; } const int N=1000055; int n,m,fail[N]; int tot,ch[N][26],val[N]; char s[N]; queue<int> q; void ins(char *s) //构建trie { int now=0; for(int i=0;s[i];i++) if(!ch[now][s[i]-'a']) ch[now][s[i]-'a']=++tot,now=ch[now][s[i]-'a']; else now=ch[now][s[i]-'a']; val[now]++; } void build() //构建fail数组和字典图 { for(int i=0;i<26;i++) if(ch[0][i]) q.push(ch[0][i]); while(!q.empty()) { int u=q.front();q.pop(); for(int i=0;i<26;i++) if(ch[u][i]) fail[ch[u][i]]=ch[fail[u]][i],q.push(ch[u][i]); else ch[u][i]=ch[fail[u]][i]; } } int query(char *s) //多模式匹配 { int now=0,ans=0; for(int i=0;s[i];i++) { now=ch[now][s[i]-'a']; for(int j=now;j&&val[j]!=-1;j=fail[j]) ans+=val[j],val[j]=-1; } return ans; } int main() { n=read(); for(int i=1;i<=n;i++) scanf("%s",s),ins(s); build(); scanf("%s",s); printf("%d\n",query(s)); return 0; }
洛谷P3796 AC自动机加强版
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; int read() { int k=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) k=k*10+c-'0';return k*f; } const int N=1000055; int n,m,fail[N],sum[N]; int tot,ch[N][26],val[N]; char t[155][75]; char s[N]; queue<int> q; void ins(int i,char *s) { int now=0; for(int i=0;s[i];i++) if(!ch[now][s[i]-'a']) ch[now][s[i]-'a']=++tot,now=ch[now][s[i]-'a']; else now=ch[now][s[i]-'a']; val[now]=i; } void build() { for(int i=0;i<26;i++) if(ch[0][i]) q.push(ch[0][i]); while(!q.empty()) { int u=q.front();q.pop(); for(int i=0;i<26;i++) if(ch[u][i]) fail[ch[u][i]]=ch[fail[u]][i],q.push(ch[u][i]); else ch[u][i]=ch[fail[u]][i]; } } int query(char *s) //多模式匹配 { int maxn=0,now=0; for(int i=0;s[i];i++) { now=ch[now][s[i]-'a']; for(int j=now;j;j=fail[j]) if(val[j]) { sum[val[j]]++; if(sum[val[j]]>maxn) maxn=sum[val[j]]; } } return maxn; } int main() { while(n=read()) { for(int i=1;i<=n;i++) scanf("%s",t[i]),ins(i,t[i]); build(); scanf("%s",s); int maxn=query(s); int ans=0; printf("%d\n",maxn); for(int i=1;i<=n;i++) if(sum[i]==maxn) printf("%s\n",t[i]); for(int i=0;i<=tot;i++) val[i]=fail[i]=0,memset(ch[i],0,sizeof(ch[i])); for(int i=1;i<=n;i++) sum[i]=0; tot=0; } return 0; }

浙公网安备 33010602011771号