AC 自动机学习笔记

打印 上一主题 下一主题

主题 918|帖子 918|积分 2754

前言

AC自动机(\(Aho\ Corasick\   Atomaton\))有着一种 \(KMP\) 的思想,所以在学习之前建议先学一下 \(KMP\)。同时还需要了解一下 \(Trie\) 树(建议去看一下 oi-wiki 上的字典树
问题描述

给定一个字符串 \(S\) 和 \(n\) 模式串,问有多少个模式串在 \(S\) 中出现过。
首先我们把 \(n\) 个模式串组成一个 \(Trie\)(就当你们学会了 \(Trie\) 树)

模式串:\(ABC,BCD,BD,C\),其中绿色的点表示字符串的结尾。
对于 \(|S|=ABCBCD\),那么我们在 \(Trie\) 上开始匹配,最开始会经过 \(2,3,4\) 三个点到 \(4\) 的时候,发现已经成功匹配了一个模式串了,那么现在我们需要从根在匹配一次吗?
显然的,不需要,\(KMP\) 的思想可以运用在这个 \(Trie\) 树上,我们在匹配完 \(4\) 的时候可以直接来到 \(7\) 然后再匹配到 \(8\)。
对于从 \(4\) 到 \(7\) 这个步骤,我们称 \(7\) 是 \(4\) 的 \(Fail\)(失配指针)。
\(Fail\) 指针

刚才说了 \(Fail\) 是失配指针,那么如果此时匹配失败,那么就到达这个指针指向的位置,所以,失配指针指向的节点是当前节点所代表的串,最长的、能与后缀匹配的,且在 \(Trie\)
中出现过的前缀所代表的节点。
我们设点 \(x\) 的父亲的 \(Fail\) 指针指向的是 \(p\),那么如果 \(p\) 的儿子 \(y\) 和 \(x\) 相同,那么 \(x\) 的 \(Fail\) 指针指向的就是 \(y\)(应该挺好理解的吧)。
那么如果没有儿子呢?
那就再造一个儿子,就把当前节点的子节点指向当前节点的 \(fail\) 节点的子节点。
而且发现每个点 \(fail\) 指向的节点都比当前节点小,那么第二层的 \(fail\) 就指向根节点。
然后对于失配指针 \(Fail\) 我们需要使用 \(BFS\) 来实现。
[code]inline void Get_fail(){        for(int i=0;i

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

三尺非寒

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表