字符串算法与自动机
字符串算法与自动机
前言
觉得字符串这个东西本身应该有一个非常系统的体系,但是之前的学习一直都是零散的。
自动机
先说说什么是自动机,其实在OI Wiki上面已经十分完备了,这里以自己的理解再总结一遍。
自动机是一种数学模型,它所针对的对象是 “信号序列”,也就是一串 具有顺序 的信号,在 OI 方面基本上是以字符串的形式展现,判断一个串是否是给定串的前缀,是不是给定串的子序列......
自动机有以下的属性:
- 字符集:限定的字符的集合。
- 状态集合:所有的状态节点。
- 起始状态:类比字典树的 \(0\) 号节点。
- 接受状态集合:一组特殊的状态,如果最后停留在这些节点,说明这个 信号序列 是可以接受的。
- 转移函数:\(\delta(i,c)\) ,表示在 \(i\) 这个节点,如果当前读入到 信号序列 中的字符是 \(c\) ,该向哪个节点转移。
Trie
字典树就是一个很典型的自动机,在根据某个串 \(s\) 遍历字典树的时候,我们都是根据当前的节点和当前遍历到的 \(s\) 的字符是什么来决定下一步往哪里走。
KMP
想一想求出了模式串的 \(nex\) 数组之后,匹配文本串的过程,实际上也还是在遍历文本串的同时,记录当前的位于的状态节点,然后根据当前遍历到的字符 \(c\) 来对状态节点进行转移。
ACAM
广义 KMP, \(nex\) 数组被扩展成了 \(fail\) 指针,这样 \(fail\) 指针就变成了转移函数 \(\delta\)。
子序列自动机
给定 \(s\) 这个字符串,对于任意的 \(t\) 串,只接受是 \(s\) 子串的 \(t\),有一个很显然地贪心,那就是从左到右去枚举 \(t\) 的字符,然后尽量取 \(s\) 最靠做的能与之对应的字符匹配,于是我们可以倒着扫一遍,就能成功构建这个自动机。
为什么要练,为什么要写?
引用一句让我幡然悔悟的话:
“练了不一定写的出来正解,不练一定写不出来正解”
本文来自博客园,作者:Hanggoash,转载请注明原文链接:https://www.cnblogs.com/Hanggoash/p/18854407

浙公网安备 33010602011771号