前言
AC 自动机并不是可以自动帮你 AC 的数据结构……
AC 自动机,可以简单地理解为 KMP+Trie 组成的东西。KMP 可以解决一个文本串对一个模式串的问题,AC 自动机则可以解决一个文本串对应多个模式串的问题。
前置芝士:
- Trie 树;
- KMP 大致原理(没学也无所谓,只是帮助理解)。
话不多说,进入正题。
原理概述
首先明确一个点:AC 自动机是基于 Trie 实现的。类似于 KMP 算法,AC 自动机也有自己独特的失配指针。
设 为 Trie 树上节点 u 失配后应从哪里开始继续匹配。
如图是一个 AC 自动机:
是的,很乱。所以,我将详细讲解失配指针是怎么来的。
失配指针
首先,我们可以明确:对于任意节点 , 的深度一定小于 的深度(不然就不叫“失配”了)。 所以,我们可以通过 bfs 求出整个 数组。
假设我们现在在 这个节点失配了, 对应的字符是 。那现在的思路就是重新找找看有没有其他的字符串是有着相同前缀的。但是,如果每一次都从根节点开始找,那就太费时了。
这时,我们将眼光投向了 的父亲 。根据条件, 肯定已经求出来了。那么,如果 有 这个节点,那 ( 数组是 Trie 树的边)。这很容易理解: 与 前缀是相同的。如果 失配了,那么我们就去尝试一下另一边是否可行。
给个图吧:
应该能理解了吧?
那么,问题来了:如果 没有 这个儿子呢?
待补充