后缀自动机(Suffix automaton)

这玩意真的是坑啊,看了很多博客都没弄懂,课业繁忙,断断续续搞了三天才刚明白大意。。。

定义介绍:

给定字符串str,建立后缀自动机

后缀自动机是什么?其实就是前缀树的压缩,存一个图的前缀树所耗费的空间太大了,我们利用字符串各个子串之间的关系去掉一些没必要出现的结点,后缀自动机有一个根节点,每次从根结点出发,到任意一个结点结束所形成的一个字符串都是str的子串

sam(str):表示字符串str的后缀自动机

endpos(有些地方是right集合)

指一个字符串s在str中出现的位置构成的集合,使用字符串s的结尾字母在str的位置代表字符串在str的位置

例:str="ABBBCDBCECG"

字符串"BC"的endpos:"5、8";字符串"C"的endpos:"5、8、10";字符串"AB"的endpos:"2"

关于endpos的一些性质:

1、endpos相同的两个字符串,其中一个一定是另一个的后缀

2、如果字符串a是字符串b的后缀,b的endpos一定是a的endpos的子集

3、对于一些endpos相同的字符串,它们一定互为后缀,且它们的长度连续

4、确定了endpos和len就能确定唯一的一个字符串

trans状态转移函数

状态state(xx):表示一个字符串集合,这个集合中的字符串的endpos都是xx(xx是一个endpos)

trans(s,c)=p  表示:当前状态是s,在其后加上一个字符c后到达状态p

状态s中的任意字符串在其后加上字符c后得到的endpos都是相同的,即都指向状态p

Parent、Parent树

shortest:状态s中字符串长度最小的一个字符串

longest:状态s中字符串长度最大的一个字符串

性质:

1、对于状态s中的shortest的任意一个后缀(不包括自己)的状态p,则有:s的endpos是p的endpos的真子集

2、状态s的shortest去掉首字母后得到的字符串一定是另一个状态的longest,这个状态我们定义为Parent状态,简记为pa状态

3、我们可以得到公式:Len(s.shortest)=Len(s.pa.longest)+1

4、s的endpos是其pa的endpos的真子集

5、如果trans(s,c)≠NULL,那么,trans(pa,c)≠NULL;因为如果trans(s,c)存在这个状态,那么pa的字符串加上字符c之后,一定        还是状态s+c的后缀,所以也一定存在trans(pa,c),所以,你可以认为状态pa完全包含状态s

6、状态pa的endpos就是它所有儿子的状态的endpos的并集

对于字符串:"ABCDBCDD"

构造后缀自动机

后缀自动机中的结点:指一个状态(字符串的集合):state(endpos(ss))(ss为从root结点到当前结点所形成的最长字符串)

知道了这些以后,我们怎么构造出str的后缀自动机呢?

我们是根据状态转移函数在线构造的,从str的首字符开始,依次添加字符进行构造,所以现在重要的是怎么进行转移的?

假设我们已经构造出sam(T),怎么构造出sam(Tx)呢?

sam(Tx)比sam(T)多了字符串Tx的所有的后缀,这些后缀都是由T的后缀+字符x转移来的(除了字符x本身,可另做考虑),所以我们要想办法找出这些结点,使得这些结点能表示出所有的这些后缀,然后把这些结点与新结点相连即可

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值