您的算法不正确。我假设您知道如何计算字符串的后缀数组和LCP数组,即它们的有效实现。正如评论中指出的那样,您应该尝试了解每个组件是什么以及它为何起作用。
首先,是字符串的后缀数组()。后缀数组基本上是按字典顺序升序排列的字符串S的所有后缀。更具体地,值小号甲[ 我]表示的后缀小号从位置开始小号甲[ 我]排名我在所有后缀的词典式排序小号。SASSA[i]SSA[i]iS
接下来是阵列。L C P [ i ]表示从S A [ i - 1 ]和S A [ i ]开始的后缀之间的最长公共前缀的长度。也就是说,当按字典顺序排列时,它会跟踪S的两个连续后缀中最长的公共前缀的长度。LCPLCP[i]SA[i−1]SA[i]S
例如,考虑字符串。按字典顺序排列的后缀为{ a ,a b b a b c a ,a b c a ,b a b c a ,b b a b c a ,b c a ,c a },因此S A = [ 7 ,1S=abbabca{a,abbabca,abca,babca,bbabca,bca,ca}对于1索引数组。的大号Ç P阵列将大号Ç P = [ - ,1 ,2 ,0 ,1 ,1 ,0 ]。SA=[7,1,4,3,2,5,6]LCPLCP= [ - ,1 ,2 ,0 ,1 , 1,0]
现在,给定两个字符串和B,我们将它们连接为S = A #B,其中#是A和B都不存在的字符。选择这种字符的原因是,当计算两个后缀的LCP(例如a b #d a b d和a b d)时,比较会在第一个字符串的末尾中断(因为它只会出现一次,两个不同的后缀永远不会在同一位置出现),也不会“溢出”到另一个字符串中。一种乙小号= A #B#一种乙a b #da b da b d
现在可以看出,您应该能够理解为什么只需要查看数组中的连续值(该参数基于矛盾以及S A中的后缀按字典顺序排列的事实)。继续检查L C P数组的最大值,以使要比较的两个后缀不属于同一原始字符串。如果它们不属于同一原始字符串(一个以A开头,另一个以B开头),则此类值中的最大值是最大的公共子字符串的长度。L CP小号一种L CP一种乙
例如,考虑和B = b c。然后,S = a b c a b c #b c。排序后缀为{ a b c #b c ,a b c a b c #b c ,b c ,b c #b c ,b c aA = a b c a b cB = b c小号= a b c a b c #b c。小号一{abc#bc,abcabc#bc,bc,bc#bc,bcabc#bc,c,c#bc,cabc#bc}
SALCP=[4,1,8,5,2,9,6,3,7]=[−,3,0,2,2,0,1,1,0]
现在,最大的值是,但它对于小号甲[ 1 ]和小号甲[ 2 ],这两者开始字符串甲。因此,我们忽略了这一点。在另一方面,大号Ç P [ 4 ] = 2为小号甲[ 3 ](对应于后缀b Ç的乙)和小号甲[ 4 ]LCP[2]=3SA[1]SA[2]ALCP[4]=2SA[3]bcBSA[4](对应于后缀的甲)。因此,这是两个字符串之间最长的公共子字符串。为了获取实际的子字符串,您可以从S A [ 3 ]或S A [ 4 ](即b c)开始,选择长度2(最大可行L C P的值)子字符串。bcabc#bcA2 LCPSA[3]SA[4]bc