%yyb
通俗易懂的ac自动机教程 : https://www.cnblogs.com/cjyyb/p/7196308.html
板子题四道:
开一篇博客存一下板子(第一题ac代码)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 3;
struct Trie {
int fail,ch[27],cnt;
}ac[maxn];
int tot=0;
void Insert(char s[])
{
int len=strlen(s),now=0;
for(int i=0;i<len;i++) {
if(!ac[now].ch[s[i]-'a']) ac[now].ch[s[i]-'a']=++tot;
now=ac[now].ch[s[i]-'a'];
}
ac[now].cnt++;
}
void build()
{
ac[0].fail=0;
queue<int> q;
for(int i=0;i<26;i++) if(ac[0].ch[i])
{
ac[ac[0].ch[i]].fail=0; q.push(ac[0].ch[i]);
}
while(!q.empty())
{
int now=q.front(); q.pop();
for(int i=0;i<26;i++)
if(ac[now].ch[i])
{
ac[ac[now].ch[i]].fail=ac[ac[now].fail].ch[i];
q.push(ac[now].ch[i]);
}
else ac[now].ch[i]=ac[ac[now].fail].ch[i];
}
}
int query(char s[])
{
int len=strlen(s),ans=0,now=0,tmp;
for(int i=0;i<len;i++) {
now=ac[now].ch[s[i]-'a'];
tmp=now;
while(tmp&&ac[tmp].cnt)
{
ans+=ac[tmp].cnt;
ac[tmp].cnt=0;
tmp=ac[tmp].fail;
}
}
return ans;
}
int main()
{
int n;
char s[maxn];
scanf("%d",&n);
for(int i=1;i<=n;i++) {
scanf("%s",s);
Insert(s);
}
build();
scanf("%s",s);
printf("%d",query(s));
return 0;
} 第四题代码(第一题改为多组数据需要每次初始化,初始化50*n的大小即可)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 3;
struct Trie {
int fail,ch[27],cnt;
}ac[maxn];
int tot=0;
void Insert(char s[])
{
int len=strlen(s),now=0;
for(int i=0;i<len;i++) {
if(!ac[now].ch[s[i]-'a']) ac[now].ch[s[i]-'a']=++tot;
now=ac[now].ch[s[i]-'a'];
}
ac[now].cnt++;
}
void build()
{
ac[0].fail=0;
queue<int> q;
for(int i=0;i<26;i++) if(ac[0].ch[i])
{
ac[ac[0].ch[i]].fail=0; q.push(ac[0].ch[i]);
}
while(!q.empty())
{
int now=q.front(); q.pop();
for(int i=0;i<26;i++)
if(ac[now].ch[i])
{
ac[ac[now].ch[i]].fail=ac[ac[now].fail].ch[i];
q.push(ac[now].ch[i]);
}
else ac[now].ch[i]=ac[ac[now].fail].ch[i];
}
}
int query(char s[])
{
int len=strlen(s),ans=0,now=0,tmp;
for(int i=0;i<len;i++) {
now=ac[now].ch[s[i]-'a'];
tmp=now;
while(tmp&&ac[tmp].cnt)
{
ans+=ac[tmp].cnt;
ac[tmp].cnt=0;
tmp=ac[tmp].fail;
}
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
char s[maxn];
scanf("%d",&n);
for(int i=0;i<=n*50;i++) {
ac[i].cnt=0;
for(int j=0;j<26;j++) ac[i].ch[j]=0;
}
for(int i=1;i<=n;i++) {
scanf("%s",s);
Insert(s);
}
build();
scanf("%s",s);
printf("%d\n",query(s));
}
return 0;
}

京公网安备 11010502036488号