介绍
ac 自动机(Aho-Corasick automaton)是一种字符串搜索算法,用于在文本中快速查找匹配的模式字符串。它由 Alfred V. Aho 和 Margaret J. Corasick 于 1975 年发明。
ac 自动机是一种确定性有限自动机,它由一组状态和一组从一个状态到另一个状态的转换组成。每个状态都与一个输出值相关联,该输出值表示在该状态下匹配的模式字符串。
Aho-Corasick 自动机的工作原理如下:
- 首先,将模式字符串预处理成一颗字典树(也称为trie树)。字典树是一种树形的数据结构,其中每个节点都代表一个字符,每个分支都代表一个可能的模式字符串。
- 然后,将文本字符串逐个字符地输入到字典树中。当一个字符与字典树中的某个节点匹配时,我们就沿着该节点对应的分支继续向下查找。
- 如果我们到达了一个叶节点,则表示我们找到了一个匹配的模式字符串。我们将叶节点对应的输出值记录下来。
- 如果我们没有找到一个匹配的模式字符串,则我们将沿着失败指针回溯到字典树中的另一个状态,然后继续查找。
Aho-Corasick 自动机之所以高效,是因为它利用了失败指针来加速搜索过程。失败指针是指向字典树中另一个状态的指针,该状态表示在当前状态找不到匹配的模式字符串时应该跳转到的状态。
通过使用失败指针,Aho-Corasick 自动机可以避免在字典树中进行不必要的搜索,从而提高搜索效率。
应用场景
ac 自动机可以用于解决各种各样的字符串搜索和模式匹配问题相关场景,包括:
- 文本搜索
- 入侵检测系统 (IDS)
- 病毒扫描软件
- 数据挖掘
- 自然语言处理 (NLP)
- 代码分析
- 网络安全
- 数据处理
- 机器翻译
- 评论检测
ac 自动机是一种非常通用的工具,可以用于解决各种各样的问题。
手撸ac自动机
核心注释
类注释
TrieNode
:AC 自动机节点类。ACAtom
:AC 自动机类。
方法注释
build(String[] patterns)
:根据模式字符串数组构建 AC 自动机。insert(String pattern)
:插入模式字符串。buildFailurePointers()
:构建失败指针。search(String text)
:在文本中搜索匹配的模式字符串,返回匹配结果列表。
属性注释
TrieNode.isEndOfWord
:是否
核心方法分析
insert
方法
用于插入模式字符串。它的实现原理如下:
- 将当前节点设置为根节点。
- 依次遍历模式字符串中的每个字符。
- 如果当前节点的子节点中不包含该字符,则创建一个新的子节点并将其添加到当前节点的子节点中。
- 将当前节点设置为新创建的子节点。
- 重复步骤 2 和 3,直到遍历完模式字符串中的所有字符。
- 将当前节点的
isEndOfWord
属性设置为true
,表示该节点对应一个模式字符串的结尾。 - 将当前节点的
matchedString
属性设置为模式字符串,以便在搜索时能够知道匹配的字符串是什么。
时间复杂度和空间复杂度分析
insert
方法的时间复杂度为 O(n),其中 n 是模式字符串的长度。这是因为insert
方法需要遍历模式字符串中的每个字符,并可能需要创建新的子节点。insert
方法的空间复杂度为 O(n),其中 n 是模式字符串的长度。这是因为insert
方法可能需要创建新的子节点,而每个子节点都需要存储一个字符和一个指向其父节点的指针。
buildFailurePointers
方法
用于构建失败指针,它的实现原理如下:
- 将根节点的失败指针设置为
null
。 - 将根节点添加到一个队列中。
- 循环队列,直到队列为空。
- 从队列中取出一个节点,并将其所有子节点添加到队列中。
- 对于该节点的每个子节点,查找该子节点对应字符在该节点的失败指针对应的节点中的子节点。
- 如果找到了,则将该子节点的失败指针设置为该节点的失败指针对应的节点中的子节点。
- 如果没有找到,则将该子节点的失败指针设置为根节点。
时间复杂度和空间复杂度分析
buildFailurePointers
方法时间复杂度:O(n^2),其中 n 是所有模式字符串的总长度。buildFailurePointers
方法空间复杂度:O(n),其中 n 是所有模式字符串的总长度。
search
方法
用于在文本中搜索匹配的模式字符串。它的实现原理如下:
- 将当前节点设置为根节点。
- 依次遍历文本字符串中的每个字符。
- 如果当前节点的子节点中包含该字符,则将当前节点设置为该子节