后缀数组中height数组的解释

前文:点我
当我在使用后缀数组中会用到一个数组为 h e i g h t height height
h e i g h t [ i ] height[i] height[i]的定义为:排在第 i i i为的后缀和排在第 i − 1 i-1 i1位的最长公共前缀
并且其应该满足下面这个定理
h e i g h t [ r n k [ i ] ] ≥ h e i g h t [ r n k [ i − 1 ] ] − 1 height[rnk[i]]\geq height[rnk[i-1]]-1 height[rnk[i]]height[rnk[i1]]1
这个定理的一种证明方法可以参考 o i . w i k i oi.wiki oi.wiki:

在这里插入图片描述
但是可以有其他的普通解释:
我们认为字符串是从左开始的,所以 i − 1 i-1 i1位应该在第 i i i位的左侧,因此 i − 1 i-1 i1位的后缀可以表示成为 a A aA aA,第 i i i位的后缀可以表示成 A A A,如果说 a A aA aA与排在他前面的后缀 S S S的最长公共前缀可以达到 k k k位,那么在 A A A中是不是一定会有 k − 1 k-1 k1位能与 A A A匹配. 那么当这 k − 1 k-1 k1位打头组成后缀时,一定紧邻 A A A,如果他们之间不紧邻,则一定有比 k − 1 k-1 k1更长的前缀紧邻 A A A,所以至少是 k − 1 k-1 k1.
我们再来看一个字符串

//源串:bdbd
//设i的后缀为dbd
//设i-1的后缀为bdbd
排序:
bd
bdbd//i-1
d
dbd//i

在这个例子里, A = d b d A=dbd A=dbd,并且至少有 d d d d b d dbd dbd紧邻
根据这个引理可以推导出下面的用法:

void cal_height()
{
	int k = 0;
	for (int i = 0; i < n; i++)
	{
		rank1[sa[i]] = i;
	}
	for (int i = 0; i < n; i++)
	{
		if (rank1[i] == 0)continue;
		int j = sa[rank1[i] - 1];
		if (k != 0)
		{
			k--;
		}//height[i]>=height[i-1]-1
		while (i + k < n&&j + k < n&&dp[i + k] == dp[j + k])k++;
		height[i] = k;
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值