Skip to content

Aho–Corasick 自动机

Aho–Corasick automaton · AC automaton

把模式 Trie 与失败链接结合成一次扫描识别多个模式的确定有限自动机。

条目类型
模型

形式陈述

设模式集合为 P={p1,,pk}。先把全部模式插入 Trie,其节点与“某个模式的某个前缀”一一对应。对节点 v(记其对应的串为 str(v)),失败链接 fail(v) 指向这样的节点:其对应串是 str(v) 的最长真后缀,且该后缀本身也是 Trie 节点;根的孩子的失败链接指向根。由于失败链接严格缩短串长,可按广度优先搜索的层序自顶向下构造。把缺失的转移补全,得到完整转移函数

δ(v,c)={w,若 Trie 中有边 vcw,δ(fail(v),c),否则

(根处无对应边时约定 δ(root,c)=root)。于是整个结构成为一台确定性有限自动机,其状态不变量为:读完文本前缀 t 后所处的状态,恰是“既为 t 的后缀、又为某模式前缀”的最长串。到达节点 v 时,失败链上所有终止节点对应的模式都在当前位置结束;用输出链接(指向失败链上最近的终止节点)可直接逐个枚举它们。设模式总长为 m、文本长为 n、报告的匹配数为 z,字母表大小视为常数时,构建耗时 O(m)(显式补全全部转移则为 O(m|Σ|)),扫描耗时 O(n+z)

直觉

单模式匹配中,KMP 算法前缀函数记住“失配之后还能保留多长的已匹配前缀”;Aho–Corasick 把这一思想搬到模式集合上:Trie 同时记住所有模式的所有前缀,失败链接则回答“当前候选走不下去时,次长的候选是谁”。关键图像是状态即匹配进度——自动机始终维护文本当前后缀所能匹配到的最深 Trie 节点,失配时不从头再来,而是退到进度稍浅、但仍然成立的候选上。于是无论模式有多少个,文本只需从左到右读一遍。

Aho–Corasick:Trie、fail 与多模式报告
例子与边界

取经典模式集 heshehishers,扫描文本 ushers:读 u 停在根;读 she 依次走到节点 she,在此报告模式 she,且该节点的失败链接指向 he,输出链接使 he 同时被报告;再读 r,节点 sher 边,沿失败链接退到 he 后走 r 边得 her;最后读 s 到达 hers 并报告之。可见较短模式 he 完全藏在失败链上——只报告当前节点自身会漏掉它,这是最常见的实现错误;而逐位置沿失败链逐个上溯又可能把单字符代价拖到与深度成正比,输出链接把这一步压缩到与实际报告数成正比。

空间与转移的表示是另一条边界:显式补全 δ 得到真正的完整 DFA,每字符 O(1) 转移,但占 Θ(m|Σ|) 空间,在大字母表(如 Unicode)下往往浪费;只存 Trie 边加失败链接则空间 O(m),单字符转移为摊还 O(1)——沿失败链的下降总量不会超过沿 Trie 边的上升总量。

嵌套模式能更清楚地展示输出链。取模式 aaaaaa,扫描文本 aaaa:读到第一个字符时报告 a;第二个位置报告 aaa;第三、第四个位置都分别报告三个、三个模式,因此匹配总数为

4+3+2=9.

自动机的状态转移仍只随文本长度线性增长,但输出这些命中本身就需要 Θ(9) 时间;一般复杂度必须写成 O(|T|+总模式长度+z),其中 z 是实际报告数。空模式会在每个边界位置匹配,重复模式也可能需要分别保留模式编号;只在 Trie 节点上存一个布尔终止标记无法表达这些语义。

推论与应用

Aho–Corasick 是多模式字符串匹配的标准工具:敏感词过滤、入侵检测的特征扫描、词典与基因序列匹配,都靠它一次扫描文本、同时命中全部模式。把自动机状态当作“当前匹配进度”,还可与动态规划组合,解决统计不含任何禁止子串的字符串个数一类问题。失败链接全体构成一棵树(fail 树),在其上做子树统计,能一次性回答“每个模式在文本中出现了多少次”。实现词法分析等任务时,稠密字母表可预填完整转移表,稀疏字母表则需在空间与失败跳转代价之间权衡。

它与静态全文索引解决的是不同工作负载。Aho–Corasick 预处理模式集、随后在线顺序读文本,以上 O(m+n+z) 是常字母表 RAM 下的确定性最坏输出敏感界;后缀树Burrows–Wheeler 变换则预处理固定文本以服务许多模式查询。rank/select把 BWT 变成可导航序列,FM-index进一步用压缩自索引换取 countlocateextract 的不同时间—空间成本。选择哪条路线取决于“模式固定还是文本固定”,不能只比较一句笼统的“线性匹配”。

参考资料
关系图谱10 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系

实现的抽象