「笔记」后缀三姐妹
写在前面
这里曾经有一篇很长的文章,由于太粪了被削除了。以下是全新的重置版本。
为什么下面有四个?四大天王有五个不也是常识吗
「笔记」后缀数组
字符串 S 的后缀数组定义为两个数组 sa,rk。
sa 储存 S 的所有后缀 按字典序排序后的起始下标,满足 S[sai−1:n]<S[sai:n]。
rk 储存 S 的所有后缀的排名。
结合后缀的最长公共前缀,后缀数组可以用来处理许多复杂度字符串问题。
「笔记」后缀树
对于一个字符串 S,它的后缀树是由其所有后缀 S[i:n](1≤i≤n) 组成的,经过信息压缩后的 Trie 树。
后缀数组可以看作由后缀树的所有叶结点按字典序排列得到的数组。
「笔记」后缀自动机
字符串 S 的后缀自动机 (suffix automaton, SAM) 是一个可以且尽可以接受 S 所有后缀的 最小的 DFA。
更形式化的定义:
- 字符串 S 的 SAM 是一张 DAWG(有向单词无环图)。节点被称作 状态,边被称作状态间的 转移。
- 存在一个起始节点,称作 起始状态。其它节点均可从起始节点出发到达。
- 每个 转移 都标有一些字母。从一个节点出发的所有转移均 不同。
- 存在数个 终止状态。若从 t0 出发,最终转移到一个终止状态,路径上所有转移连接起来一定是 S 的一个后缀。S 的每个后缀均可用一条 从起始节点到某个终止状态 的路径构成。
- 在所有满足上述条件的 DFA 中,SAM 的节点数是最少的。
SAM 并不是一个典型的 DFA,在 DAWG 基础上,除 t0 外的每个状态都被添加了一条 后缀链接。所有后缀链接组成了树状结构,这棵树被称为 parent 树。
字符串 S 的 SAM 能包含 S 所有子串的信息。
SAM 将这些信息以高度压缩的形式储存,对于一个长度为 n 的字符串,它的 SAM 空间复杂度仅为 O(n),构建 SAM 的时间复杂度也仅为 O(n)。
「笔记」广义后缀自动机
广义 SAM 是一种用于维护 Trie 的子串信息的 SAM 的简单变体。
将多个模式串插入到 Trie 后,即可使用广义 SAM 维护多模式串的信息。这是广义 SAM 最广泛的应用之一,本文的重点也在于此。其基本思想是将多串的信息进行压缩,使得 SAM 在仍满足节点数最少的同时 包含所有子串的信息。此时 SAM 中的一个状态可能同时代表多个串中相应的子串。
作者@Luckyblock,转载请声明出处。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】博客园携手 AI 驱动开发工具商 Chat2DB 推出联合终身会员
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 聊一聊 C#异步 任务延续的三种底层玩法
· 敏捷开发:如何高效开每日站会
· 为什么 .NET8线程池 容易引发线程饥饿
· golang自带的死锁检测并非银弹
· 如何做好软件架构师
· 欧阳的2024年终总结,迷茫,重生与失业
· Bolt.new 30秒做了一个网站,还能自动部署,难道要吊打 Cursor?
· 史上最全的Cursor IDE教程
· 关于产品设计的思考
· 我的编程之路 2024