其他分享
首页 > 其他分享> > 后缀自动机 (SAM) 学习笔记

后缀自动机 (SAM) 学习笔记

作者:互联网

定义

后缀自动机(\(\text{Suffix Automaton}\),简称 \(\text{SAM}\))是一种用于字符串处理的有限状态自动机(\(\text{DFA}\)),它根据母串的所有后缀构建,能识别出母串的所有子串,且构造算法复杂度接近线性,实际上是 \(O(n\log |\Sigma|)\),\(|\Sigma|\) 是字符集大小,这里将 \(|\Sigma|\) 看作常数。

\(\textbf{SAM}\) 的性质

基础性质

边的种类

后缀自动机上有两种边:

\(\textbf{Endpos}\)

定义

一个子串在母串中出现的位置的右端点形成的集合。

例如母串 \(S=\texttt{abbcab}\),子串 \(T=\texttt{ab}\),则 \(\text{endpos}(\texttt{ab})=\{2,6\}\),即 \(T=S[1\sim2],S[5\sim6]\)。

则可以得到,一个 \(\text{endpos}\) 集合可能对应多个子串。

\(\text{SAM}\) 中的一个节点的状态与一个 \(\text{endpos}\) 集合相互对应,所以不存在两个不同节点的状态对应同一个 \(\text{endpos}\) 集合,每个节点对应的 \(\text{endpos}\) 集合互不相同。

性质

记 \(\mathcal {Q}_{T}\) 表示子串 \(T\) 的 \(\text{endpos}\) 集合,\(|T|\) 表示字符串 \(T\) 的长度。

\(\textbf{Parent Tree}\)

根据定义比较难理解,可以考虑下图,母串 \(S=\texttt{aababa}\)。

性质

记 \(\mathcal{R}_{T}\) 表示子串 \(T\) 出现但以 \(T\) 为后缀的子串 \(T'\) 都不出现的位置集合,\(\mathcal{U}_{x}\) 表示节点 \(x\) 的 \(\text{endpos}\) 集合,\(\text{Min}_x\) 表示节点 \(x\) 的最短子串,\(\text{Max}_{x}\) 表示节点 \(x\) 的最长子串,\(\text{son}_x\) 表示节点 \(x\) 的子节点构成的点集。

根据这两个性质可以分析出沿着 \(\text{Parent}\) 链向上跳本质上就是不断从后缀中删去前缀的过程,也可以分析出点数最多有 \(2n\) 个(考虑多个子节点的 \(\text{endpos}\) 集合大小越接近时点数越多,也就是等比数列求和),进一步得到边数最多为 \(3n\) 条(\(2n\) 个点的生成树占据 \(2n-1\) 条,母串最多有 \(n\) 个不同的后缀,从源点走到不能再走的点代表一种后缀,最多 \(n\) 条,加起来最多 \(3n\) 条)。

构建后缀自动机

运用增量法构造,假如已经构建完母串的前缀 \(S[1\sim n]\) 的后缀自动机,在此基础上增加第 \(n+1\) 个字符 \(S_{n+1}\) 形成新的后缀自动机。

加入第 \(n+1\) 个字符时一共有 \(3\) 种情况(下面举例时假设已经构建好 ab 的后缀自动机):

该例子不仅包含了该后缀自动机的构建,也包含了总体的三种情况,实现时按照三种情况分类讨论即可。

代码实现

struct Node{
	int son[26],len,fa;
	Node(){ memset(son,0,sizeof son); len=fa=0; }
} node[N<<1];
int last=1,tot=1; //last 表示前缀 S[1~n] 的节点,tot 表示 SAM 的总节点数
inline void add(int c){
	int p=last,nw=last=++tot; node[nw].len=node[p].len+1; //新建一个节点
	for (; p&&!node[p].son[c]; p=node[p].fa) node[p].son[c]=nw; //跳父链将节点的出边连向新节点
	if (!p) node[nw].fa=1; //情况1: 源点
	else {
		int q=node[p].son[c];
		if (node[q].len==node[p].len+1) node[nw].fa=q; //情况2: p -> q
		else {
			int xq=++tot; //情况3: t -> q
			node[xq]=node[q]; node[xq].len=node[p].len+1; node[q].fa=node[nw].fa=xq;
			for (; p&&node[p].son[c]==q; p=node[p].fa) node[p].son[c]=xq;
		}
	}
}

标签:子串,SAM,后缀,text,源点,mathcal,自动机,节点
来源: https://www.cnblogs.com/Samsara-soul/p/suffix-autumaton-study-notes.html