SAM的构造

sam实质:将一个字符串高度压缩后的后缀放入一个自动机内,使得这个自动机可以接受所有文本的字串

endpos:字串末尾在原串中出现位置的集合

parent tree:若一个节点的endpos是另一个的子集,那么parent tree有一条由母集到子集的边

自动机中,每个状态代表的是endpos集合相等的一些字符串

添加字符是分三种情况

令未加入这个字符的为原串,las为原串所在节点

1.没有这个字符:las所在链上所有点向新节点连边

2.若有

        2.1.若本来这个字符和原串的某个后缀一起出现在字符串的某个地方过,就让新节点向表示原串某后缀+新字符这个节点连边

        2.2否则复制这个节点,将他看作是代表原串某后缀+新字符的一个节点,再进行一系列操作

	void insert(char ch){
		int now=++sz;
		mes[now].len=mes[las].len+1;
		while(las&&!mes[las].nxt[ch]) mes[las].nxt[ch]=now,las=mes[las].fa;//连转移
		if(!las) mes[now].fa=1;//没有出现过这个字符
		else{
			int to=mes[las].nxt[ch];
			if(mes[to].len==mes[las].len+1) mes[now].fa=to;//2.1种情况
			else{//2.2种情况:复制节点
				int np=++sz;
				mes[np]=mes[to],mes[np].len=mes[las].len+1;
				while(las&&mes[las].nxt[ch]==to) mes[las].nxt[ch]=np,las=mes[las].fa;
				mes[to].fa=mes[now].fa=np;
			}
		}
		las=now;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值