题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222
题意:判断一个文章内包含多少个模式串(可能有重复)。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int kind = 26;
struct node
{
node *fail;
node *next[kind];
int cnt;
node()
{
fail = NULL;
cnt = 0;
memset(next, 0, sizeof(next));
}
}*q[500005];
char keyword[55];
char str[1000005];
int head, tail;
void Trie_insert(node *root, char *str)
{
int index, i = 0;
node *p = root;
while(str[i])
{
index = str[i] - 'a';
if(p -> next[index] == NULL)
p -> next[index] = new node();
p = p -> next[index];
i++;
}
p -> cnt++;
}
void build_ac_automation(node *root)
{
head = 0;tail = 1;
root -> fail = NULL;
q[head] = root;
while(head < tail)
{
node *temp = q[head++];
node *p = NULL;
for(int i = 0; i < 26; i++)
{
if(temp -> next[i] != NULL)
{
if(temp == root)
temp -> next[i] -> fail = root;
else
{
p = temp -> fail;
while(p != NULL)
{
if(p -> next[i] != NULL)
{
temp -> next[i] -> fail = p -> next[i];
break;
}
p = p -> fail;
}
if(p == NULL)
temp -> next[i] -> fail = root;
}
q[tail++] = temp -> next[i];
}
}
}
}
int query(node *root)
{
int i = 0, cnt = 0, index, len = strlen(str);
node *p = root;
while(str[i])
{
index = str[i] - 'a';
while(p -> next[index] == NULL && p != root)
p = p -> fail;
p = p -> next[index];
p = (p == NULL) ? root : p;
node *temp = p;
while(temp != root && temp -> cnt != -1)
{
cnt += temp -> cnt;
temp -> cnt = -1;
temp = temp -> fail;
}
i++;
}
return cnt;
}
int main()
{
int n, T;
scanf("%d", &T);
while(T--)
{
//head = tail = 0;
node *root = new node();
scanf("%d", &n);
getchar();
while(n--)
{
gets(keyword);
Trie_insert(root, keyword);
}
build_ac_automation(root);
scanf("%s", &str);
printf("%d\n", query(root));
}
return 0;
}