程序功能
求文本串中出现了多少模式串
[链接](http://acm.hdu.edu.cn/showproblem.php?pid=2222)
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxkind = 26;
char text[1000005],pattern[55];
struct Node
{
Node *fail;
Node *next[maxkind];
int cnt;
Node() { fail = NULL; memset(next,0,sizeof(next)); cnt = 0; }
};
struct myACMachine
{
Node *root;
myACMachine()
{
root = new Node();
}
~myACMachine()
{
destroy(root);
delete root;
}
void destroy(Node *rt)
{
if(!rt) return;
for(int i=0; i<26; i++)
destroy(rt->next[i]);
}
void Insert(char *str)
{
int len = strlen(str);
Node *p = root;
for(int i=0; i<len; i++)
{
int index = str[i] - 'a';
if(p->next[index] == NULL) p->next[index] = new Node();
p = p->next[index];
}
p->cnt++;
}
void getACMachine()
{
queue<Node*>Q;
Q.push(root);
while(!Q.empty())
{
Node *father = Q.front(); Q.pop();
for(int i = 0; i < 26; i++)
{
Node *son = father->next[i];
if(son != NULL)
{
Node *temp = father->fail;
while(temp != NULL && temp->next[i] == NULL)
temp = temp->fail;
if(temp == NULL)
son->fail = root;
else
son->fail = temp->next[i];
Q.push(son);
}
}
}
}
int query(char *text)
{
int len = strlen(text),ans = 0;
Node *p = root;
for(int i=0; i<len; i++)
{
int index = text[i] - 'a';
while(p != NULL && p->next[index] == NULL)
p = p->fail;
if(p == NULL) p = root;
else
{
p = p->next[index];
Node *temp = p;
while(temp!=root && temp->cnt)
{
ans += temp->cnt;
temp->cnt = 0;
temp = temp->fail;
}
}
}
return ans;
}
};
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
myACMachine ac;
int n;
scanf("%d",&n);
while(n--)
{
scanf("%s",pattern);
ac.Insert(pattern);
}
ac.getACMachine();
scanf("%s",text);
printf("%d\n",ac.query(text));
}
return 0;
}