@@ -18,10 +18,119 @@ AC 自动机的构造有 3 个步骤:
1818
1919### 2.1 构造一棵字典树(Trie)
2020
21- 首先我们需要建立一棵字典树。
21+ 首先我们需要建立一棵字典树。字典树是一种树形数据结构,用于高效地存储和检索字符串集合。每个节点代表一个字符,从根节点到某个节点的路径上的字符连接起来,就是该节点对应的字符串。
22+
23+ 对于给定的 5 个单词,构造的字典树如下:
24+
25+ ```
26+ root
27+ / \
28+ s h
29+ / \ |
30+ a h e
31+ / / \ \
32+ y e r r
33+ ```
2234
2335### 2.2 构造失配指针
2436
37+ 失配指针(fail pointer)是 AC 自动机的核心。当在字典树中匹配失败时,失配指针指向另一个节点,该节点对应的字符串是当前节点对应字符串的最长后缀。
38+
39+ 失配指针的构造过程:
40+ 1 . 根节点的失配指针指向空
41+ 2 . 对于每个节点,其失配指针指向其父节点的失配指针指向的节点的对应子节点
42+ 3 . 如果对应子节点不存在,则继续沿着失配指针向上查找
43+
2544### 2.3 扫描文本串
2645
27- ## 3. AC 自动机的应用
46+ 扫描文本串的过程:
47+ 1 . 从根节点开始,按照文本串的字符顺序在字典树中移动
48+ 2 . 如果当前字符匹配成功,继续移动到下一个字符
49+ 3 . 如果当前字符匹配失败,通过失配指针跳转到另一个节点继续匹配
50+ 4 . 当到达某个单词的结束节点时,说明找到了一个匹配的单词
51+
52+ ## 3. AC 自动机的应用
53+
54+ AC 自动机在以下场景中有着广泛的应用:
55+
56+ 1 . ** 多模式字符串匹配** :在文本中查找多个模式串
57+ 2 . ** 敏感词过滤** :检测文本中是否包含敏感词
58+ 3 . ** DNA序列分析** :在生物信息学中用于DNA序列的模式匹配
59+ 4 . ** 网络入侵检测** :检测网络数据包中的恶意模式
60+ 5 . ** 拼写检查** :检查文本中的拼写错误
61+
62+ ## 4. AC 自动机的实现
63+
64+ ### 4.1 时间复杂度
65+
66+ - 构建字典树:O(Σ|P|),其中 P 是所有模式串的集合
67+ - 构建失配指针:O(Σ|P|)
68+ - 文本串匹配:O(n + k),其中 n 是文本串长度,k 是匹配的模式串数量
69+
70+ ### 4.2 空间复杂度
71+
72+ - O(Σ|P|),其中 Σ 是字符集大小
73+
74+ ## 5. 代码实现
75+
76+ ``` python
77+ class TrieNode :
78+ def __init__ (self ):
79+ self .children = {} # 子节点
80+ self .fail = None # 失配指针
81+ self .is_end = False # 是否是单词结尾
82+ self .word = " " # 存储完整的单词
83+
84+ class AC_Automaton :
85+ def __init__ (self ):
86+ self .root = TrieNode()
87+
88+ def add_word (self , word ):
89+ node = self .root
90+ for char in word:
91+ if char not in node.children:
92+ node.children[char] = TrieNode()
93+ node = node.children[char]
94+ node.is_end = True
95+ node.word = word
96+
97+ def build_fail_pointers (self ):
98+ queue = []
99+ # 将根节点的子节点的失配指针指向根节点
100+ for char, node in self .root.children.items():
101+ node.fail = self .root
102+ queue.append(node)
103+
104+ # 广度优先搜索构建失配指针
105+ while queue:
106+ current = queue.pop(0 )
107+ for char, child in current.children.items():
108+ fail = current.fail
109+ while fail and char not in fail.children:
110+ fail = fail.fail
111+ child.fail = fail.children[char] if fail else self .root
112+ queue.append(child)
113+
114+ def search (self , text ):
115+ result = []
116+ current = self .root
117+
118+ for char in text:
119+ while current is not self .root and char not in current.children:
120+ current = current.fail
121+ if char in current.children:
122+ current = current.children[char]
123+
124+ # 检查当前节点是否是某个单词的结尾
125+ temp = current
126+ while temp is not self .root:
127+ if temp.is_end:
128+ result.append(temp.word)
129+ temp = temp.fail
130+
131+ return result
132+ ```
133+
134+ ## 6. 总结
135+
136+ AC 自动机是一种高效的多模式匹配算法,它通过结合字典树和 KMP 算法的思想,实现了在文本串中快速查找多个模式串的功能。虽然其实现相对复杂,但在需要多模式匹配的场景下,AC 自动机提供了最优的时间复杂度。
0 commit comments