“Suffix array保存后缀的字典序排列,是后缀树叶序的线性化,通常更紧凑但查询依赖二分、LCP 或额外索引。Suffix automaton压缩的是子串的右端等价类,把全部状态设为接受…”
形式陈述
转移图与接受语言
给定长度为
包括空后缀。后缀自动机(suffix automaton,SAM)是识别这一后缀语言的最小确定部分自动机:没有对应转移就拒绝。相对于总转移 DFA,它省略了空残余的拒绝陷阱态;补回该态即可得到最小完整 DFA。
同一转移图也支持子串查询。每个子串都是某个后缀的前缀,因此从初态能完整读出
endpos 类与后缀链接
对非空子串
的各个类。初态单独对应空前缀。每个状态
同一类的短串必为长串的后缀:取长串的一次出现,两者在同一位置结束。夹在两者之间的后缀,其 endpos 又夹在相同的两个集合之间,因此也属于该类。由此,一个非初态恰包含最长代表在以下各长度上的后缀,每个长度一个:
所以它贡献 ab 与 b 共享 endpos
为什么后缀识别器最小
相对于
不同结束位置留下的后缀长度不同,因此这个集合与 endpos 集合一一对应。相同 endpos 给出同一残余,不同 endpos 给出不同残余;初态还允许续写整个
某状态接受后缀,恰当且仅当它的 endpos 含 last,再沿后缀链接标记到初态。
直觉
SAM 合并的是“在文本的哪些位置结束”,而不是任意两段看起来相似的字符串。末尾再加一个字符时,某些旧的 endpos 类需要分开:较短成员可能获得一次新出现,较长成员却没有。clone 用来记录这次结构分裂,不代表多读入了一个字符。
后缀语言的残余恰能区分这些结束位置,所以 endpos 给出最小后缀识别器。只问子串成员时,可以忽略终止标记而检查转移是否存在;这项便利来自同一图的路径结构,最小性仍须相对于选定语言判断。
例子与边界
两种接受规则不共享最小性结论
在图中的 ababa 状态图里,读取 bab 能到状态 baa 时缺少转移,所以不是子串。若只识别后缀,接受态则是 last 的链接链;状态 bab 不是 ababa 的后缀。
再看 b 的 endpos 为 ab 的 endpos 为
在线扩展与 clone
维护已经处理前缀的状态 last。读入字符
- 若没有遇到已有转移,令
为初态。 - 若
,直接令 。 - 否则新建
,复制 的出边与原后缀链接,令其长度为 。从当前 继续沿链接向上,把仍通过 指向 的边改指向 ,直到遇到不同转移或越过初态;最后令 的链接都指向 。
随后令
经典构造的转移总数也是
子串计数与出现次数
不同非空子串数为
对 ababa,各非初态贡献 len 降序向链接父亲累加。这把每个真实末位置贡献给包含它的 endpos 类;clone 本身没有新增末位置,初值为
若只按不同回文内容建索引,回文树采用另一种节点划分:一种回文一个节点,没有SAM的endpos等价类或clone。它也可沿后缀链接汇总出现次数,但扩展边表示两端同时加同一字符,不能当作本页自动机逐字符读取的转移。
推论与应用
SAM 支持子串成员查询、不同子串计数、出现次数与最长公共子串。按字典序查第
后缀树按前缀共享压缩后缀,后缀数组与 FM-index 围绕后缀序建立静态索引。SAM 的 endpos 图不直接给出 suffix-array 区间、位置列表或文本提取;这些查询需要另加信息与相应的时间、空间分析。
参考资料
- Jean Berstel, Luc Boasson, Olivier Carton and Isabelle Fagnot, Minimization of Automata, 2010,§9.1:后缀自动机的最小后缀语言定义与线性规模;§2:残余语言与最小性。
- Maxime Crochemore and Wojciech Rytter, Jewels of Stringology, World Scientific, 2002, Chapter 5.
- Anselm Blumer et al., “The Smallest Automaton Recognizing the Subwords of a Text,” Theoretical Computer Science 40, 1985, pp. 31–55:最小子串识别器这一相关但不同的对象。