AC自动机

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;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 文不达意,口齿不清,思想混乱,令人喷饭。(估计只有我自己才能看懂我在说什么)简书没有mathjax公式没法愉快显示...
    njzwj阅读 4,894评论 1 2
  • DNA Sequence题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DN...
    Gitfan阅读 3,468评论 0 0
  • AC自动机学习记录 参考资料 字典树(讲解+模版)AC自动机算法AC自动机算法详解hdu 2222 ac自动机入门...
    染微言阅读 3,365评论 0 2
  • 类似于week2,3;然后这一节题目说是Trie图,其实用AC自动机更容易搜出来结果。对于一个M<=10^6的字符...
    vaisy阅读 1,558评论 0 0
  • AC自动机: 求多个字符串是否在主串中出现过。可依据情况分别求出出现次数,出现位置等。 AC自动机入门Keywor...
    Gitfan阅读 1,616评论 0 0

友情链接更多精彩内容