http://acm.hdu.edu.cn/showproblem.php?pid=5880
AC自动机模板题,唯一不同的地方就是多一个长度数组,记录该状态为结尾状态时整个串的长度
之后当前状态进入到终结状态时 把这一段全部改变为*即可
#include <bits/stdc++.h>
#define mme(i,j) memset(i,j,sizeof(i))
#define maxs 2202020
using namespace std;
char s[maxs];
class Ac_automatic
{
public:
int nexts[maxs][26],ends[maxs],fail[maxs],les[maxs];
int root,L,bk[maxs];
int newnode()
{
for(int i=0;i<26;i++)
nexts[L][i]=-1;
les[L]=0;
ends[L++]=-1;
return L-1;
}
void init()
{
L = 0;
root = newnode();
}
void Insert(char *s)
{
int len=strlen(s);
int id,now = root;
for(int i=0;i<len;i++)
{
id = s[i]-'a';
if(nexts[now][id]==-1)
nexts[now][id]=newnode();
now = nexts[now][id];
}
ends[now]=1;
les[now] = len;
}
void build()
{
int now = root ,id;
queue<int>q;
fail[root]=root;
for(int i=0;i<26;i++)
if(nexts[now][i]==-1)
nexts[now][i]=root;
else
{
fail[ nexts[root][i] ] = root;
q.push(nexts[root][i]);
}
while(!q.empty())
{
now = q.front();
q.pop();
for(int i=0;i<26;i++)
{
if(nexts[now][i]==-1)
nexts[now][i] = nexts[ fail[now]][i];
else{
fail[ nexts[now][i] ] = nexts[ fail[now] ][i];
q.push(nexts[now][i]);
}
}
}
}
void query(char *s)
{
int id;
int len=strlen(s);
int now =root;
mme(bk,0);
for(int i=0;i<len;i++)
{
if(s[i]>='A'&&s[i]<='Z') id = s[i]-'A';
else if(s[i]>='a'&&s[i]<='z') id = s[i]-'a';
else continue;
now = nexts[now][id];
int tmp = now;
while(tmp!=root)
{
if(ends[tmp]!= -1)
{
for(int j=i;j>=i-les[tmp]+1;j--)
{
s[j]='*';
}
break;
}
tmp = fail[tmp];
}
}
puts(s);
}
}ac;
char str[maxs];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
ac.init();
for(int i=0;i<n;i++)
{
scanf("%s",str);
ac.Insert(str);
}
ac.build();
getchar();
gets(s);
ac.query(s);
}
return 0;
}