hdu 2222 Keywords Search 典型的AC自动机入门题目

hdu 2222 Keywords Search 典型的AC自动机入门题目

前段时间学会了trie树之后,今天终于学习了一下AC自动机,这个还是挺难学的,现在我还是有点不太懂,参照了网上的代码才把这道题给A了。
让我自己背着写出来还不一定会写。这里有一篇比较好的介绍AC自动机的文章http://www.cppblog.com/mythit/archive/2009/04/21/80633.html
先看一下这道题吧,大意是给我们一部字典和一个模式串,让我们求出字典中有多少个单词在模式串的子串,开始一直TLE,我都郁闷了,最后让acmost
看了一下,他让我把 for (int i = 0 ;i < strle(s); i++) 里面的strlen(s)改一下试试,我改为了s[i],果然一下就过了,原来每次都计算strlen(s)会增加复杂度,太菜了
帖下代码:
  

  1 #include < iostream >
  2 #include < queue >
  3 using   namespace  std;
  4
  5 struct  node {
  6    int isword;
  7    node *fail;
  8    node *next[26];
  9    void init(){
 10        isword=0;
 11        fail=0;
 12        memset(next,0,sizeof(next));
 13    }

 14}
;
 15
 16 node  set [ 500000 ];
 17 node  * root;
 18 int  cot;
 19 char  ch[ 1000005 ];
 20
 21 void  insert( char  s[])
 22 {
 23    if(!root){
 24        set[cot].init();
 25        root=&set[cot++];
 26    }

 27    node *pos=root;
 28    for(int i=0;s[i];i++){
 29        int k=s[i]-'a';
 30        if(!pos->next[k]){
 31            set[cot].init();
 32            pos->next[k]=&set[cot++];
 33            pos=pos->next[k];
 34        }

 35        else pos=pos->next[k];
 36    }

 37    pos->isword++;
 38}

 39 void  input()
 40 {
 41    int n;
 42    char s[55];
 43    scanf("%d",&n);
 44    for(int i=1;i<=n;i++){
 45        scanf("%s",s);
 46        insert(s);
 47    }

 48    scanf("%s",ch);
 49}

 50
 51 void  build_ac()
 52 {
 53    queue<node *> myque;
 54    myque.push(root);
 55    while(!myque.empty()){
 56        node *tp=myque.front();
 57        myque.pop();
 58        for(int i=0;i<26;i++){
 59            if(tp->next[i]){
 60                if(tp==root)
 61                    tp->next[i]->fail=root;
 62                else{
 63                    node *pos=tp->fail;
 64                    while(pos){
 65                        if(pos->next[i]){
 66                            tp->next[i]->fail=pos->next[i];
 67                            break;
 68                        }

 69                        pos=pos->fail;
 70                    }

 71                    if(pos==0) tp->next[i]->fail=root;
 72                }

 73                myque.push(tp->next[i]);
 74            }

 75        }

 76    }

 77}

 78
 79 int  query()
 80 {
 81    int ans=0;
 82    node *tp=root;
 83    for(int i=0;ch[i];i++){
 84        int k=ch[i]-'a';
 85        if(tp->next[k])
 86            tp=tp->next[k];
 87        else{
 88            while(tp!=root&&!tp->next[k])
 89                tp=tp->fail;
 90            if(!tp->next[k]) tp=root;
 91            else tp=tp->next[k];
 92        }

 93        node *pos=tp;
 94        while(pos!=root&&pos->isword>=0){
 95            ans+=pos->isword;
 96            pos->isword=-1;
 97            pos=pos->fail;
 98        }

 99    }

100    return ans;
101}

102 int  main()
103 {
104    int t;
105    scanf("%d",&t);
106    while(t--){
107        root=0;
108        cot=0;
109        input();
110        build_ac();
111        int ans=query();
112        printf("%d\n",ans);
113    }

114    return 0;
115}

116

你可能感兴趣的:(hdu 2222 Keywords Search 典型的AC自动机入门题目)