HDU[2222] Keywords Search
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222
AC自动机常用于多模字符串匹配问题
代码如下:
#include<cstring>
#include<ctype.h>
#include<cstdio>
#include<queue>
#define N 1000050
using namespace std;
inline int read(){
int x;
scanf("%d",&x);
return x;
}
int T,n;
char c[N];
struct Node{
Node *nex,*ch[26];
bool b;
int num;
Node():nex(NULL),b(false),num(0){
for(int i=0;i<26;i++)
ch[i]=NULL;
}
}*root;
struct Aho_Corasick_Automaton{
inline void Insert(char *c){
int len=strlen(c+1);
Node *x=root;
for(int i=1;i<=len;i++){
int k=c[i]-'a';
if(x->ch[k]==NULL) x->ch[k]=new Node;
x=x->ch[k];
}
x->num++;
}
inline void GetFail(){
queue<Node*>q;
Node *x=root;
for(int i=0;i<26;i++){
if(x->ch[i]!=NULL) q.push(x->ch[i]),x->ch[i]->nex=x;
else x->ch[i]=x;
}
while(!q.empty()){
x=q.front();q.pop();
for(int i=0;i<26;i++){
if(x->ch[i]!=NULL) q.push(x->ch[i]),x->ch[i]->nex=x->nex->ch[i];
else x->ch[i]=x->nex->ch[i];
}
Node *tmp=x;
tmp=tmp->nex;
while(tmp!=root && !tmp->num) tmp=tmp->nex;
x->nex=tmp;
}
return;
}
inline int Match(char *c){
int len=strlen(c+1);
int ans=0;
Node *x=root;
for(int i=1;i<=len;i++){
int k=c[i]-'a';
x=x->ch[k];
Node *tmp=x;
while(tmp!=root && !tmp->b){
ans+=tmp->num,tmp->b=true;
tmp=tmp->nex;
}
}
return ans;
}
}AC;
int main(){
T=read();
while(T--){
root=new Node;
n=read();
for(int i=1;i<=n;i++){
scanf("%s",c+1);
AC.Insert(c);
}
AC.GetFail();
scanf("%s",c+1);
printf("%d\n",AC.Match(c));
}
return 0;
}