第一道AC自动机
在hihocoder的第1036 题“Trie图”,在题目看到了Trie图的讲解,当时看的有一点没明白,然后索性就去搜索AC自动机的讲解
http://blog.youkuaiyun.com/niushuai666/article/details/7002823
看的这篇博客的讲解,然后又读了好多遍博主给出的一个例题的代码才看懂AC自动机,例题是:
http://blog.youkuaiyun.com/niushuai666/article/details/7002736
然后把例题自己又写了一遍。
#include <cstdio>
#include <cstring>
struct node
{
node *fail;
int cnt;
node *next[26];
node()
{
cnt = 0;
fail = NULL;
memset(next,0,sizeof(next));
}
};
char keyword[51];
char str[1000010];
node *que[500010];
node *root;
int head,tail;
void Insert(char* str)
{
node *p = root;
int len = strlen(str);
int id;
for(int i = 0; i < len; ++i)
{
id = str[i] - 'a';
if(p->next[id] == NULL)
p->next[id] = new node;
p = p->next[id];
}
++p->cnt;
}
void buildAc()
{
que[tail++] = root;
while(head != tail)
{
node *p = que[head++];
node *temp = NULL;
for(int i = 0; i < 26; ++i)
{
if(p->next[i] != NULL)
{
if(p == root)
p->next[i]->fail = root;
else
{
temp = p->fail;
while(temp != NULL)
{
if(temp->next[i] != NULL)
{
p->next[i]->fail = temp->next[i];
break;
}
temp = temp->fail;
}
if(temp == NULL)
p->next[i]->fail = root;
}
que[tail++] = p->next[i];
}
}
}
}
int query()
{
int index,result;
node *p = root;
result = 0;
int len = strlen(str);
for(int i = 0; i < len; ++i)
{
index = str[i] - 'a';
while(p->next[index] == NULL && p != root)
p = p->fail;
p = p->next[index];
if(p == NULL)
p = root;
node *temp = p;
while(temp != root && temp->cnt != -1)
{
result += temp->cnt;
temp->cnt = -1;
temp = temp->fail;
}
}
return result;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
head = tail = 0;
root = new node;
scanf("%d",&n);
for(int i = 0; i < n; ++i)
{
scanf("%s",keyword);
Insert(keyword);
}
buildAc();
scanf("%s",str);
printf("%d\n",query());
}
return 0;
}