美文网首页
AC自动机

AC自动机

作者: fo0Old | 来源:发表于2017-04-14 14:28 被阅读0次
    struct AhoCorasickAutomaton
    {
        static const int alp=26;
    
        static int to_idx(char ch)
        {
            return ch-'a'+1;
        }
    
        struct Trie
        {
            static const int __=1000005;
            struct node
            {
                int nex[alp+1],last,num;
                bool add[alp+1];
                void clear()
                {
                    num=last=0;
                    mem(nex,0);
                    mem(add,false);
                }
            }t[__];
    
            Trie() {clear();}
    
            node& operator[](int x){return t[x];}
    
            int idx;
    
            void insert(char s[],int len)
            {
                int x=0;
                for(int i=1;i<=len;++i)
                {
                    int k=to_idx(s[i]);
                    if(!t[x].nex[k])
                    {
                        t[x].nex[k]=++idx;
                        t[idx].clear();
                    }
                    x=t[x].nex[k];
                }
                //标记结尾
            }
    
            void clear(){idx=0;t[0].clear();}
        }t;
    
        AhoCorasickAutomaton() {clear();}
    
    #define nex(x) t[x].nex[i]
    #define fail(x) t[x].nex[0]
    
        void get_fail()
        {
            queue<int>Q;Q.push(0);
            while(!Q.empty())
            {
                int x=Q.front();Q.pop();
                for(int i=1;i<=alp;++i)
                    if(nex(x))
                    {
                        Q.push(nex(x));
    //                    for(int y=x;y;y=fail(y))
    //                        if(nex(fail(y)))
    //                        {
    //                            fail(nex(x))=nex(fail(y));
    //                            break;
    //                        }
                        if(x)fail(nex(x))=nex(fail(x));
                    }
                    else
                    {
                        nex(x)=nex(fail(x));
                        t[x].add[i]=true;
                    }
                if(t[fail(x)].num)t[x].last=fail(x);
                else t[x].last=t[fail(x)].last;
    
            }
        }
    
        int ac(char s[],int len)
        {
            int ans=0;
            for(int i=1,x=0;i<=len;++i)
            {
                int k=to_idx(s[i]);
    //            while(x && !t[x].nex[k])x=fail(x);
                x=t[x].nex[k];
                for(int y=x;y;y=t[y].last)
                    ;//统计答案
            }
            return ans;
        }
    
        void debug()
        {
            for(int i=0;i<=t.idx;++i)
            {
                pf("t[%d]: fail:%d last:%d\n",i,fail(i),t[i].last);
                for(int j=1;j<=26;++j)
                    if(t[i].nex[j])
                        printf("%d(%c) ",t[i].nex[j],j-1+'a');
                puts("\n");
            }
        }
    
        void clear(){t.clear();}
    }aca;
    

    相关文章

      网友评论

          本文标题:AC自动机

          本文链接:https://www.haomeiwen.com/subject/rvbvattx.html