您的位置:首页 > 其它

NYOJ 1085 AC自动机基础模板

2014-10-18 10:36 274 查看
今天学了AC自动机,可以说AC自动机是把匹配的串建立成为一颗trie,然后就和kmp 是一样的

题意:判断在一篇文章中有多少单词出现过,并输出来

#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<iostream>
using namespace std;
const int maxn = 1000007;
int cnt;
struct Node{
Node *fail;
Node *next[27];
int count,id;
Node(){
memset(next,NULL,sizeof(next));
fail = NULL;
count = 0 ,id = -1;
}
};
char word[200][108];
int keymap[200],ret[200];
char str[maxn];
int Max;
void insert(int pos,char *str,Node *root){
Node *p = root;
int i=0,index;
while(str[i]){
index = str[i] - 'a';
if(p -> next[index] == NULL)
p -> next[index] = new Node();
p = p->next[index];i++;
}
if(!p->count){
p->id = cnt++;
p ->count = 1;
} keymap[pos] = p->id;
}
void Build_AC_auto(Node *root){
queue <Node*> s;
root -> fail = NULL;
s.push (root);
while(!s.empty()){
Node *tmp = s.front();s.pop();
Node *p   = NULL;
for(int i=0;i<26;i++){
if(tmp ->next[i]){
if(tmp == root)tmp->next[i]->fail = root;
else {
p = tmp->fail;
while(p){
if(p->next[i]){
tmp -> next[i] -> fail = p -> next[i];
break;
}
p = p -> fail;
}
if(!p)tmp->next[i]->fail = root;
}
s.push(tmp -> next[i]);
}
}
}
}
void query(Node *root){
int i=0;
Node *p = root;
while(str[i]){
int index = str[i] - 'a';
while(!p->next[index] && p!=root)p = p->fail;
p = p->next[index];
p = (p == NULL) ? root : p;
Node *tmp = p;
while(tmp !=root ){//puts("yes");
if(tmp ->count){
ret[tmp ->id]++;
if(ret[tmp ->id]> Max){
Max = ret[tmp -> id];
}
}
tmp = tmp->fail;
}
i++;
}
}
int main(){
int t,n,m;
freopen("input.txt","r",stdin);
scanf("%d",&t);
while(t --){
Max = 0;cnt =0 ;
Node *root = new Node();
scanf("%d",&n);
memset(ret,0,sizeof(ret));
for(int i=0;i<n;i++){
scanf("%s",word[i]);
insert(i,word[i],root);
}
Build_AC_auto(root);
scanf("%s",str);
query(root);
printf("%d\n",Max);
for(int i=0;i<n;i++){
if(ret[keymap[i]]== Max){
printf("%s\n",word[i]);
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: