AC自动机 重点总结

算法大致过程及分析

前几天瞎搞了ac自动机模板,本文将ac自动机算法较重要的地方及实现细节记录下来。
AC自动机是著名的多串模式匹配算法。
形式上说,就是一堆模式串,一个文本串,可以将模式串与文本串匹配。
大体实现就是将所有模式串存到一个trie里,匹配就在trie上面走,若失配则走失配指针到一个最优的能继续匹配的结点。
当然,在匹配的时候,会有下面这种情况需要特殊判断

盗个图,哈(此图原出处
模式串有ac,abc,bc
文本串为acabc
那么匹配了abc之后,bc就被忽略了,但事实上也要被匹配到。
那么这些遗漏的串都是abc的后缀,所以要沿着fail链往上找。
这里有一个小优化
我们就可以在求fail链的时候顺带求出一个点fail链上最近一个单词末尾的结点,设为up[v]
那么匹配了v点就沿着up链往上走即可。
并不知道效果怎么样。
L表示模式串总长度,N表示文本串总长度
时间复杂度是O(L+N)
本蒟蒻并不会证明,感性理解吧
因为不可能每一次都能沿fail链跳很多步,跳着跳着就跳到根了,要再有跳很多步的机会又要匹配很多字符
上面一行纯属扯淡

代码实现及注意事项

  • 个人习惯把1设为trie的根
  • trie的存储依题而定,或许可以26个指针,有时卡空间的话要用模拟链表
  • 如果多组数据要记得清空tot,trie[][],标记数组,最好不要memset
  • 建fail参见下面代码
void bfs()
{
    q.push(1);
    while(!q.empty())
    {
        int v=q.front();q.pop();
        fo(i,0,25)
            if(trie[v][i])
            {
                int x=trie[v][i],y=fail[v];
                while(y && !trie[y][i]) y=fail[y];
                if(y) fail[x]=trie[y][i];
                else fail[x]=1;
                q.push(x);
            }
    }
}

匹配是这个样子的

        int x=1;
        fo(i,1,len)
        {
            int y=s[i]-'a';
            while(x!=1 && !trie[x][y]) x=fail[x];
            if(trie[x][y]) x=trie[x][y];
            for(int v=x;v!=1;v=fail[v])
            {
                //这里视题目而定
            }
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值