NYOJ 1085 AC自动机基础模板

来源:互联网 发布:全球黑客攻击源码 编辑:程序博客网 时间:2024/05/21 17:52

今天学了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]);            }        }    }}


0 0
原创粉丝点击