后缀数组—heigh

前缀数组:height数组,height[i]=suffix(sa[i-1])和suffix(sa[i])的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀


它有以下两个性质:

1:对于i和j,假设有rank[ i ]<rank[ j ],那么rank[ i ]同rank[ j ]的相同的前缀数是height[rank[i]+1],height[rank[i]+2], height[rank[i]+3],……, height[rank[j]]中的最小值


2:定义h[i]=height[rank[i]],也就是suffix(i)和在它前一名的后缀的最长公共前缀。那我们有h[i]≥h[i-1]-1。

证明:设suffix(k)是排在suffix(i-1)前一名的后缀,则它们的最长公共前缀是h[i-1]。那么suffix(k+1)将排在suffix(i)的前面(这里要求h[i-1]>1。如果h[i-1]≤1,原式右边小于等于0,显然成立)并且suffix(k+1)和suffix(i)的最长公共前缀是h[i-1]-1,所以suffix(i)和在它前一名的后缀的最长公共前缀至少是h[i-1]-1。

如图,因为suffix(i)与suffix(i-1)排名不一定相邻,又因为排名相邻的两个后缀拥有的前缀是最多的(即多于h[i]),所以h[i]一定会大于等于h[i-1]-1。


按照h[1],h[2],……,h[n]的顺序计算,并利用h数组的性质,时间复杂度可以降为O(n)。


代码:


void get_height(int n)  
{
	int k=0;  
	for(int i=1;i<=n;i++)  
	{  
	    int j=sa[rank[i]-1];  
	    if(k) k--;//k表示height[rank[i]-1]的值,即h[i-1]  
      
	    while(a[i+k]==a[j+k]) k++;  
	    height[rank[i]]=k;  
	}  
}


推荐:《后缀数组—sa与rank》http://blog.csdn.net/a_bright_ch/article/details/53454088

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值