ac自动机模板题
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
const int kind=100;
using namespace std;
char b[201],a[10001]; //a模式串,b为匹配串
int mark[501];
struct trie{
struct trie * fail,*next[kind];
int count; //count表示是第几个模式串
trie(){
fail=NULL;
count=0;
memset(next,NULL,sizeof(next));
}
};
struct trie * root;
void insert(char* str,int count){
int len=strlen(str),i,tem;
struct trie *p,*q;
p=root;
for(i=0;i<len;i++){
tem=str[i]-32;
if(p->next[tem]==NULL){
q=(struct trie*)calloc(1,sizeof(struct trie));
q->count=0;
q->fail=NULL;
memset(q->next,NULL,sizeof(q->next));
p->next[tem]=q;
}
p=p->next[tem];
}
p->count=count;
}
void buildac(){
int i;
struct trie *p,*tem;
queue<struct trie *>q;
root->fail=NULL;
q.push(root);
while(!q.empty()){
tem=q.front();
q.pop();
for(i=0;i<100;i++){
if(tem->next[i]!=NULL){
if(tem==root)
tem->next[i]->fail=root;
else{
p=tem->fail;
while(p!=NULL){
if(p->next[i]!=NULL){
tem->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL)
tem->next[i]->fail=root;
}
q.push(tem->next[i]);
}
}
}
}
bool query(char *str){
int len=strlen(str),i,tem,result=0;
struct trie* tmp=root,*p;
bool flag=0;
for(i=0;i<len;i++){
tem=str[i]-32;
while(tmp->next[tem]==NULL && tmp!=root)
tmp=tmp->fail;
tmp=tmp->next[tem];
if(tmp==NULL)
tmp=root;
p=tmp;
while(p!=root){ //每到一个位置就加上p->count,以及以他的后缀为前缀的单词
if(p->count!=0){
mark[p->count]=1;
flag=1;
}
p=p->fail;
}
}
return flag;
}
int main(){
int t,T,n,i,j,total=0;
scanf("%d",&n);
root=(struct trie*)calloc(1,sizeof(struct trie));
root->fail=NULL;
root->count=0;
memset(root->next,NULL,sizeof(root->next));
for(i=1;i<=n;i++){
scanf("%s",b);
insert(b,i);
}
buildac();
scanf("%d",&T);
for(t=1;t<=T;t++){
memset(mark,0,sizeof(mark));
scanf("%s",a);
if(query(a)==0)continue;
printf("web %d: ",t);
bool flag=0;
for(i=1;i<=n;i++){
if(mark[i]){
if(flag)
printf(" ");
else
flag=1;
printf("%d",i);
}
}
printf("\n");
total++;
}
printf("total: %d\n",total);
}