Aho-Corasick Automaton · AC自动机

Aho-Corasick Automaton · AC自动机

AC自动机是一个高效的字符串多模匹配算法,它的核心想法是把KMP的失配指针做到Trie上,从而实现对于所有模板字符串而言的单次文本串扫描出结果。由此可见,若要整下AC自动机,必须先掌握Trie和KMP。另外,AC自动机真的不是自动帮你AC的机子 其实你可以找AK自动机
注意,下文涉及的Trie以及KMP主要为AC自动机做铺垫,详细算法介绍请见相应文章!

·字典树(Trie)

其实字典树、前缀树什么的是同一个东西。
这里写图片描述
不难看出,树上每个节点都对应了一个单词。Trie就是这样一颗多叉树(26叉较常用,图中省略了空子树),它的边用一个大小为26的数组记录,这样就可以实现O(1)向下查找。例如单词“tea”,它对应树中路径root (第零层) > 1-1(第一层左往右第一个) > 2-2 > 3-1 。
插入:从根开始,顺着边往下走(O(1)递进,实现见代码),当走到词的末位时标记当前节点
查询:从根开始,顺着边往下走(中途走不通视为查询失败),当走到词的末位时检查当前节点,确认是否被标记。
实现方法:市面上 有两种:数组模拟和充斥着指针的动态实现,建议初学者使用静态数组,dalao们请随意

代码一言不合就封装

class Trie
{
private:
    class Nodes 
    {
    public:
        Nodes* nxt[26];
        bool end;
        Nodes()
        {
            for(int i=0;i<26;++i)
                nxt[i]=NULL;
            end=false;
        }
        void init()
        {
            for(int i=0;i<26;++i)
                nxt[i]=NULL;
            end=false;
        }
    };
    Nodes root,*now;
public:
    Trie()
    {
        this->root.init();
        this->now=NULL;
    }
    void init()
    {
        this->root.init();
        this->now=NULL;
    }
    int insert(const char *s)
    {
        if(!s)
            return 0;
        this->now=&this->root;
        for(int i=0;s[i];++i)
        {
            char ch=(s[i]>='a'&&s[i]<='z'?s[i]-'a':s[i]-'A');//假定大小写通用
            //一般情况下这样写: char ch=s[i]-'a';
            if(!this->now->nxt[ch])
            {
                if((this->now->nxt[ch]=new Nodes)==NULL)
                {
                    return -1;//申请内存失败,返回错误信息
                }
            }
            this->now=this->now->nxt[ch];
        }
        this->now->end=true;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值