AC 自动机 模板

简单版

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <queue>
using namespace std;
const int MAXN=1000005;
int n;
char s[MAXN];
struct ACAM{
	int nxt[MAXN][26],end[MAXN],fail[MAXN],nume;
	ACAM(){
		memset(nxt,0,sizeof(nxt));
		memset(end,0,sizeof(end));
		memset(fail,0,sizeof(fail));
		nume=0;
	}
	void ins(char s[]){
		int len=strlen(s);
		int p=0;
		for(int i=0;i<len;i++){
			int v=s[i]-'a';
			if(!nxt[p][v]) nxt[p][v]=++nume;
			p=nxt[p][v];
		}
		end[p]++;
	}
	void getfail(){
		queue <int>q;
		for(int i=0;i<26;i++) if(nxt[0][i]) fail[nxt[0][i]]=0,q.push(nxt[0][i]);
		int p=0;
		while(!q.empty()){
			p=q.front();q.pop();
			for(int i=0;i<26;i++){
				if(nxt[p][i]) fail[nxt[p][i]]=nxt[fail[p]][i],q.push(nxt[p][i]);
				else nxt[p][i]=nxt[fail[p]][i];
			}
		}
	}
	int query(char s[]){
		int len=strlen(s);
		int p=0,ans=0;
		for(int i=0;i<len;i++){
			p=nxt[p][s[i]-'a'];    //注意这里是s[i]-'a' 
			for(int k=p;k&&(~end[k]);k=fail[k]) ans+=end[k],end[k]=-1;
		}
		return ans;
	}
}AC;
int main(){
	freopen("in.txt","r",stdin);
	cin>>n;
	for(int i=1;i<=n;i++) scanf("%s",s),AC.ins(s);
	AC.getfail();
	scanf("%s",s);int ans=AC.query(s);
	printf("%d
",ans);
	fclose(stdin);
	return 0;
}

增强版

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <queue>
#define RST(a) memset((a),0,sizeof((a)))
using namespace std;
const int MAXN=1e6+10,MAXM=152*72;
int n;
char s[152][72],t[MAXN];
struct ACAM{
	int nxt[MAXM][26],fail[MAXM],end[MAXM],nume,cnt[MAXM],lst[MAXN];
	bool f[MAXM];
	void clear(){
		RST(nxt);RST(fail),RST(end),RST(cnt);nume=0;RST(lst);
	}
	void ins(char s[],int index){
		int len=strlen(s);
		int p=0;
		for(int i=0;i<len;i++){
			int v=s[i]-'a';
			if(!nxt[p][v]) nxt[p][v]=++nume;
			p=nxt[p][v];
		}
		end[p]=index;
	}
	void getfail(){
		queue <int> q;
		for(int i=0;i<26;i++) if(nxt[0][i]) fail[nxt[0][i]]=0,q.push(nxt[0][i]);
		int p=0;
		while(!q.empty()){
			p=q.front(),q.pop();
			for(int i=0;i<26;i++){
				int v=nxt[p][i];
				if(v) {
					fail[v]=nxt[fail[p]][i],q.push(v);
					lst[v]=end[fail[v]]?fail[v]:lst[fail[v]];
				}
				else nxt[p][i]=nxt[fail[p]][i];
			}
		}
	}
	int query(char t[]){
		int len=strlen(t);
		int p=0;
		for(int i=0;i<len;i++){
			p=nxt[p][t[i]-'a'];
			if(end[p]) cnt[end[p]]++;
			for(int k=lst[p];k;k=lst[k]) cnt[end[k]]++;
		}
		int res=0;
		for(int i=1;i<=n;i++) res=max(res,cnt[i]);
		printf("%d
",res);
		for(int i=1;i<=n;i++) if(cnt[i]==res) printf("%s
",s[i]);
	}
}AC;
int main(){
	freopen("in.txt","r",stdin);
	scanf("%d",&n);
	while(n){
		AC.clear();
		for(int i=1;i<=n;i++){
			 scanf("%s",s[i]);//cout<<s[i]<<endl;
			 AC.ins(s[i],i);
		}
		AC.getfail();
		scanf("%s",t);
		AC.query(t);
		scanf("%d",&n);
	}
	fclose(stdin);
	return 0;
}

原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8029281.html