1212
1313如果只使用字典树(Trie),虽然能够共享前缀,但每次匹配失败都必须回到根节点重新开始,无法实现高效跳转,最坏情况下复杂度也接近 $O(n \times m)$。
1414
15-
16-
17-
1815### 1.2 AC 自动机高效匹配原理
1916
2017AC 自动机能够高效解决多模式匹配问题,其核心思想是:将所有模式串构建为一棵字典树(Trie),并为每个节点设置失配指针(fail 指针),结合 KMP 算法的失配机制,实现对文本串的一次扫描即可同时匹配多个模式串。
@@ -65,9 +62,9 @@ AC 自动机的时间复杂度为 $O(n + m + k)$,其中 $n$ 为文本串长度
6562
6663失配指针的构造遵循以下规则:
6764
68- 1 . ** 根节点** :失配指针为 ` null `
69- 2 . ** 根节点的子节点** :失配指针都指向根节点
70- 3 . ** 其他节点** :从父节点的失配指针开始查找,如果找到对应字符的子节点,则指向该子节点;否则继续向上查找,直到找到或到达根节点
65+ 1 . ** 根节点** :失配指针为 ` null ` 。
66+ 2 . ** 根节点的子节点** :失配指针都指向根节点。
67+ 3 . ** 其他节点** :从父节点的失配指针开始查找,如果找到对应字符的子节点,则指向该子节点;否则继续向上查找,直到找到或到达根节点。
7168
7269#### 2.2.3 构造示例
7370
@@ -84,36 +81,37 @@ AC 自动机的时间复杂度为 $O(n + m + k)$,其中 $n$ 为文本串长度
8481```
8582
8683** 失配指针构造过程** :
84+
8785- ` s ` → ` root ` (根节点子节点指向根节点)
8886- ` h ` → ` root ` (根节点子节点指向根节点)
8987- ` sa ` → ` root ` (根节点没有 ` a ` 子节点)
9088- ` sh ` → ` h ` (根节点有 ` h ` 子节点)
91- - ` he ` → ` e ` (根节点有 ` e ` 子节点)
92- - ` hr ` → ` root ` (根节点没有 ` r ` 子节点)
9389- ` say ` → ` root ` (根节点没有 ` y ` 子节点)
9490- ` she ` → ` he ` (` h ` 节点有 ` e ` 子节点)
9591- ` shr ` → ` root ` (` h ` 和根节点都没有 ` r ` 子节点)
96- - ` her ` → ` root ` (` e ` 和根节点都没有 ` r ` 子节点)
92+ - ` he ` → ` root ` (根节点没有 ` e ` 子节点)
93+ - ` her ` → ` root ` (` root ` 没有 ` r ` 子节点)
9794
9895#### 2.2.4 失配指针的作用
9996
10097失配指针的主要作用是:
101- 1 . ** 快速跳转** :匹配失败时,不需要回到根节点重新开始
102- 2 . ** 避免重复比较** :利用已匹配的部分信息,避免重复比较
103- 3 . ** 保证匹配连续性** :确保跳转后当前匹配的字符串仍是某个模式串的前缀
98+
99+ 1 . ** 快速跳转** :匹配失败时,不需要回到根节点重新开始。
100+ 2 . ** 避免重复比较** :利用已匹配的部分信息,避免重复比较。
101+ 3 . ** 保证匹配连续性** :确保跳转后当前匹配的字符串仍是某个模式串的前缀。
104102
105103### 2.3 文本串匹配过程
106104
107105有了字典树和失配指针,我们就可以进行高效的文本串匹配了。
108106
109107#### 2.3.1 匹配算法流程
110108
111- 1 . ** 初始化** :从根节点开始
109+ 1 . ** 初始化** :从根节点开始。
1121102 . ** 字符匹配** :对于文本串中的每个字符:
113- - 如果当前节点有对应字符的子节点,移动到该子节点
114- - 否则,沿着失配指针向上查找,直到找到匹配的子节点或到达根节点
115- 3 . ** 模式串检测** :每到达一个节点,检查该节点是否为某个模式串的结尾
116- 4 . ** 输出匹配结果** :如果找到匹配的模式串,记录其位置和内容
111+ - 如果当前节点有对应字符的子节点,移动到该子节点。
112+ - 否则,沿着失配指针向上查找,直到找到匹配的子节点或到达根节点。
113+ 3 . ** 模式串检测** :每到达一个节点,检查该节点是否为某个模式串的结尾。
114+ 4 . ** 输出匹配结果** :如果找到匹配的模式串,记录其位置和内容。
117115
118116#### 2.3.2 匹配过程示例
119117
@@ -125,12 +123,12 @@ AC 自动机的时间复杂度为 $O(n + m + k)$,其中 $n$ 为文本串长度
125123| ` a ` | 根节点 | 无匹配,保持根节点 | - | - |
126124| ` s ` | 根节点 | 移动到 ` s ` 节点 | ` s ` | - |
127125| ` h ` | ` s ` 节点 | 移动到 ` sh ` 节点 | ` sh ` | - |
128- | ` e ` | ` sh ` 节点 | 移动到 ` she ` 节点 | ` she ` | ** 找到 ` she ` ** |
129- | ` r ` | ` she ` 节点 | 失配,跳转到根节点 | - | - |
130- | ` h ` | 根节点 | 移动到 ` h ` 节点 | ` h ` | - |
131- | ` s ` | ` h ` 节点 | 失配,跳转到根节点 ,再移动到 ` s ` 节点 | ` s ` | - |
126+ | ` e ` | ` sh ` 节点 | 移动到 ` she ` 节点 | ` she ` | ** 找到 ` she ` 、 ` he ` ** (沿 fail 链) |
127+ | ` r ` | ` she ` 节点 | 失配,沿 fail 跳到 ` he ` ,再转移到 ` her ` 节点 | ` her ` | ** 找到 ` her ` ** |
128+ | ` h ` | ` her ` 节点 | 失配,跳到根节点,再移动到 ` h ` 节点 | ` h ` | - |
129+ | ` s ` | ` h ` 节点 | 失配,跳到根节点 ,再移动到 ` s ` 节点 | ` s ` | - |
132130
133- ** 最终结果** :在文本串 ` yasherhs ` 中找到模式串 ` she ` (位置 2-4 )。
131+ ** 最终结果** :在文本串 ` yasherhs ` 中找到模式串 ` she ` (位置 3-5)、 ` he ` (位置 4-5)、 ` her ` (位置 4-6 )。
134132
135133
136134## 3. AC 自动机代码实现
0 commit comments