Commit 17279694 authored by sshwy's avatar sshwy
Browse files

添加KMP自动机和确定有限状态自动机的拓展

parent ff9dbb89
Loading
Loading
Loading
Loading
+23 −10
Original line number Diff line number Diff line
@@ -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)
@@ -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} =
@@ -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$ 。