后缀自动机(SAM)
对OI WIKI进行了抄写删减
定义
字符串
-
SAM是一张有向无环图。节点称作状态,边称作转移
-
图存在一个源点
,称作初始状态(即下图红点),其他节点均可从 出发到达 -
转移依赖字符进行
-
存在一个或多个终止状态(下图绿点)
-
在满足以上的同时节点数最少
可看作对字符串所有后缀建Trie树,然后对相同的状态(即下文endpos集合相同)缩点
以aaba为例
以abbb为例
线性构造
先明确一些概念
结束位置endpos
字符串s的任意非空子串t,记
两个子串endpos集合可能相等:
SAM中每个状态对应一个或多个endpos相同的子串。加上初始状态,SAM的状态个数等于endpos相同的一个或多个子串组成的集合个数+1。
lemma1
两个非空子串 u 和 w(假设 ∣u∣≤∣w∣)的 endpos 相同,当且仅当字符串 u 是 w 的后缀。
lemma2
考虑两个非空子串
lemma3
将一个endpos等价类中所有子串按长度递增排序,长度形成连续段
后缀链接link
对于一个状态p,link指向最近的一个q,
以abcbc为例,link构成一棵树,父亲是儿子的最大后缀
最大长度len
对于一个状态p,其表示的所有子串中最大长度为len,最小长度为minlen
考虑一个子串,其endpos与p有交且长度在minlen到len之间,则这个子串包含在状态p中,印证lemma3
在考虑一个子串,其endpos与p有交且长度小于minlen,则这个子串是p在link上的祖先。于是得到
在link树上,从根到叶子的一支,其子串的长度是连续的,且上为下的后缀
到现在你可以发现,后缀自动机中的后缀只存于link关系中,而节点存的是子串
过程
一开始只包含一个状态
现加入一个字符
创建新状态cur,lst为加入上一个的状态,首先就有
然后从lst开始向上跳link,对其添加字符
假设现在我们找到了一个状态p,其可以通过字符
记向 SAM 中插入当前字符
转移
仍以abcbc为例,此时向abcb加入c
我们复制状态
将从
最后一步我们将一些到
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤