Loading docs/string/ac-automaton.md +23 −10 Original line number Diff line number Diff line Loading @@ -160,6 +160,8 @@ int query(char *t) { ~~希望~~大家看懂了文章。其实总结一下,你只需要知道 AC 自动机的板子很好背就行啦。 时间复杂度:AC 自动机的时间复杂度在需要找到所有匹配位置时是 $O(|s|+m)$ ,其中 $|s|$ 表示文本串的长度, $m$ 表示模板串的总匹配次数;而只需要求是否匹配时时间复杂度为 $O(|s|)$ 。 ???+ note "模板 1" [LuoguP3808【模板】AC 自动机(简单版)](https://www.luogu.org/problemnew/show/P3808) Loading Loading @@ -281,17 +283,27 @@ int query(char *t) { } ``` ## KMP 自动机 ## 拓展 ### 确定有限状态自动机 如果大家理解了上面的讲解,那么做为拓展延伸,文末我们简单介绍一下自动机与 KMP 自动机。(现在你再去看百科上自动机的定义就会好懂很多啦) 最后介绍自动机和 KMP 自动机,供学有余力的朋友观赏。 有限状态自动机 (deterministic finite automaton,DFA)是由 有限状态自动机 (DFA):字符集,有限状态控制,初始状态,接受状态。 1. 状态集合 $Q$; 2. 字符集 $\Sigma$; 3. 状态转移函数 $\delta:Q\times \Sigma \to Q$,即 $\delta(q,\sigma)=q',\ q,q'\in Q,\sigma\in \Sigma$; 4. 一个开始状态 $s\in Q$; 5. 一个接收的状态集合 $F\subseteq Q$。 KMP 自动机:一个不断读入待匹配串,每次匹配时走到接受状态的 DFA。 组成的五元组 $(Q,\Sigma,\delta,s,F)$。 共有 $m$ 个状态,第 $i$ 个状态表示已经匹配了前 $i$ 个字符。 那这东西你用 AC 自动机理解,状态集合就是字典树(图)的结点;字符集就是`a`到`z`(或者更多);状态转移函数就是 $trans(u,c)$ 的函数(即`tr[u,c]`);开始状态就是字典树的根结点;接收状态就是你在字典树中标记的字符串结尾结点组成的集合。 定义 $trans_{i,c}$ 表示状态 $i$ 读入字符 $c$ 后到达的状态, $next_{i}$ 表示[prefix function](/string/prefix-function),则有: ### KMP 自动机 KMP 自动机就是一个不断读入待匹配串,每次匹配时走到接受状态的 DFA。如果共有 $m$ 个状态,第 $i$ 个状态表示已经匹配了前 $i$ 个字符。那么我们定义 $trans_{i,c}$ 表示状态 $i$ 读入字符 $c$ 后到达的状态, $next_{i}$ 表示 [prefix function](/string/prefix-function),则有: $$ trans_{i,c} = Loading @@ -303,8 +315,9 @@ $$ (约定 $next_{0}=0$ ) 我们发现 $trans_{i}$ 只依赖于之前的值,所以可以跟[KMP](/string/prefix-function/##knuth-morris-pratt)一起求出来。 我们发现 $trans_{i}$ 只依赖于之前的值,所以可以跟 [KMP](/string/prefix-function/#knuth-morris-pratt) 一起求出来。 时间和空间复杂度: $O(m|\Sigma|)$ 。一些细节:走到接受状态之后立即转移到该状态的 $next$ 。 时间和空间复杂度: $O(m|\Sigma|)$ 。 对比之下,AC 自动机其实就是 Trie 上的自动机。(虽然一开始丢给你这句话可能不知所措) 一些细节:走到接受状态之后立即转移到该状态的 $next$ 。 Loading
docs/string/ac-automaton.md +23 −10 Original line number Diff line number Diff line Loading @@ -160,6 +160,8 @@ int query(char *t) { ~~希望~~大家看懂了文章。其实总结一下,你只需要知道 AC 自动机的板子很好背就行啦。 时间复杂度:AC 自动机的时间复杂度在需要找到所有匹配位置时是 $O(|s|+m)$ ,其中 $|s|$ 表示文本串的长度, $m$ 表示模板串的总匹配次数;而只需要求是否匹配时时间复杂度为 $O(|s|)$ 。 ???+ note "模板 1" [LuoguP3808【模板】AC 自动机(简单版)](https://www.luogu.org/problemnew/show/P3808) Loading Loading @@ -281,17 +283,27 @@ int query(char *t) { } ``` ## KMP 自动机 ## 拓展 ### 确定有限状态自动机 如果大家理解了上面的讲解,那么做为拓展延伸,文末我们简单介绍一下自动机与 KMP 自动机。(现在你再去看百科上自动机的定义就会好懂很多啦) 最后介绍自动机和 KMP 自动机,供学有余力的朋友观赏。 有限状态自动机 (deterministic finite automaton,DFA)是由 有限状态自动机 (DFA):字符集,有限状态控制,初始状态,接受状态。 1. 状态集合 $Q$; 2. 字符集 $\Sigma$; 3. 状态转移函数 $\delta:Q\times \Sigma \to Q$,即 $\delta(q,\sigma)=q',\ q,q'\in Q,\sigma\in \Sigma$; 4. 一个开始状态 $s\in Q$; 5. 一个接收的状态集合 $F\subseteq Q$。 KMP 自动机:一个不断读入待匹配串,每次匹配时走到接受状态的 DFA。 组成的五元组 $(Q,\Sigma,\delta,s,F)$。 共有 $m$ 个状态,第 $i$ 个状态表示已经匹配了前 $i$ 个字符。 那这东西你用 AC 自动机理解,状态集合就是字典树(图)的结点;字符集就是`a`到`z`(或者更多);状态转移函数就是 $trans(u,c)$ 的函数(即`tr[u,c]`);开始状态就是字典树的根结点;接收状态就是你在字典树中标记的字符串结尾结点组成的集合。 定义 $trans_{i,c}$ 表示状态 $i$ 读入字符 $c$ 后到达的状态, $next_{i}$ 表示[prefix function](/string/prefix-function),则有: ### KMP 自动机 KMP 自动机就是一个不断读入待匹配串,每次匹配时走到接受状态的 DFA。如果共有 $m$ 个状态,第 $i$ 个状态表示已经匹配了前 $i$ 个字符。那么我们定义 $trans_{i,c}$ 表示状态 $i$ 读入字符 $c$ 后到达的状态, $next_{i}$ 表示 [prefix function](/string/prefix-function),则有: $$ trans_{i,c} = Loading @@ -303,8 +315,9 @@ $$ (约定 $next_{0}=0$ ) 我们发现 $trans_{i}$ 只依赖于之前的值,所以可以跟[KMP](/string/prefix-function/##knuth-morris-pratt)一起求出来。 我们发现 $trans_{i}$ 只依赖于之前的值,所以可以跟 [KMP](/string/prefix-function/#knuth-morris-pratt) 一起求出来。 时间和空间复杂度: $O(m|\Sigma|)$ 。一些细节:走到接受状态之后立即转移到该状态的 $next$ 。 时间和空间复杂度: $O(m|\Sigma|)$ 。 对比之下,AC 自动机其实就是 Trie 上的自动机。(虽然一开始丢给你这句话可能不知所措) 一些细节:走到接受状态之后立即转移到该状态的 $next$ 。