Title:
Chinese question.
Explanation:
AC template problem, add an array ans to this template problem to indicate the number of viruses.
Extras:
This problem let me find that I still can't understand the direction of the fail pointer in the AC automaton very well. At first, I saw that there would be overlaps. I wanted to do the same as KMP overlaps. When it is matched, it points to the point where the mismatch pointer of the node points, and then it points to itself...
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
const int MAXN=2000000+7;
struct node
{
int sum;
int number;
node *fail;
node *next[128];
node(){
fail=0;
sum=0;
number=0;
for(int i=0;i<128;i++)
next[i]=0;
}
}*root;
char c[1007][57];
char str[MAXN];
int tot;
int ans[1007];
void insert(char *s)
{
node *r=root;
for(int i=0;s[i];i++)
{
int x=s[i];
if(r->next[x]==0) r->next[x]=new(node);
r=r->next[x];
}
r->number=tot++;
r->sum++;
}
void getfail()
{
queue<node *>q;
q.push(root);
node *p;
node *temp;
while(!q.empty())
{
temp=q.front();
q.pop();
for(int i=0;i<128;i++)
{
if(temp->next[i])
{
if(temp==root)
{
temp->next[i]->fail=root;
}
else
{
p=temp->fail;
while(p)
{
if(p->next[i])
{
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==0)
temp->next[i]->fail=root;
}
q.push(temp->next[i]);
}
}
}
}
void ac_automation(char *s)
{
node *p=root;
int len=strlen(s);
for(int i=0;i<len;i++)
{
int x=s[i];
while(!p->next[x]&&p!=root) p=p->fail;
p=p->next[x];
if(!p) p=root;
node *temp=p;
while(temp!=root)
{
if(temp->sum>=0)
{
ans[temp->number]++;
}
else
break;
temp=temp->fail;
}
}
}
void del(node *head)
{
for(int i=0;i<128;i++)
if(head->next[i])
del(head->next[i]);
delete(head);
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(ans,0,sizeof(ans));
root=new(node);
tot=1;
for(int i=1;i<=n;i++)
{
scanf("%s",c[i]);
insert(c[i]);
}
getfail();
scanf("%s",str);
ac_automation(str);
for(int i=1;i<=n;i++)
if(ans[i])
printf("%s: %d\n",c[i],ans[i]);
del(root);
}
}