您的位置:首页 > 其它

AC自动机模板

2016-09-22 07:11 127 查看
用  HDU2222   这题作为模板
#include <bits/stdc++.h>

using namespace std;

struct ACautoman{
int endsum;
ACautoman *next[26];
ACautoman *fail;
ACautoman (){
endsum = 0;
fail = NULL;
memset(next,NULL,sizeof(next));
}
}*root;

void CreatTrie(char *str){
ACautoman *p = root;
int len = strlen(str);
for(int i=0; i<len; i++){
if(!p -> next[ str[i]-'a' ]) p -> next[ str[i]-'a' ] = new ACautoman;
p = p -> next[ str[i]-'a' ];
}
++(p -> endsum);
}

void CreatFail(){
queue <ACautoman *> Q;
Q.push(root);
while(!Q.empty()){
ACautoman *p = Q.front();
Q.pop();
for(int i=0; i<26; i++){
if(p -> next[i]){
if(p == root) p -> next[i] -> fail = root;
else{
ACautoman *now = p;
while(now -> fail){
if(now -> fail -> next[i]){
p -> next[i] -> fail = now -> fail -> next[i];
break;
}
now = now -> fail;
}
if(!now -> fail) p -> next[i] -> fail = root;
}
Q.push(p -> next[i]);
}
}
}
}

int Search(char *str){
int ans = 0;
int len = strlen(str);
ACautoman *p = root;
for(int i=0; i<len; i++){
while(p != root && !p -> next[ str[i]-'a' ]) p = p -> fail;
if( p -> next[ str[i]-'a' ] ){
p = p -> next[ str[i]-'a' ];
ACautoman *now = p;
while(now != root ){
if(now -> endsum){
ans += now -> endsum;
now -> endsum = 0;
}
now = now -> fail;
}
}
}
return ans;
}

const int maxn = 1000005;
char text[maxn];

int main()
{
ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--){
root = new ACautoman;
int N;
cin>>N;
char word[55];
for(int i=0; i<N; i++){
cin>>word;
CreatTrie(word);
}
cin>>text;
CreatFail();
cout<< Search(text) <<endl;
}
return 0;
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: