![](/img/trans.png)
[英]Longest common substring via suffix array: do we really need unique sentinels?
[英]Longest common substring via suffix array: uses of sentinel
我正在阅读有关一系列字符串中最长的公共子字符串的(显然)众所周知的问题,并且一直在关注这两个视频,它们讨论了如何使用后缀数组解决问题:(请注意,此问题不需要您观看它们):
第一步,我们首先将所有源字符串连接成一个大字符串,并用一个“唯一”标记来分隔每个源字符串,其中每个标记的ASCII码小于任何字符串中可能出现的任何字符。 所以我们可以有单独的字符串
abca
bcad
daca
并连接他们给
abca#bcad$daca%
现在,只有少量的可能的标记,如果我们有大量的字符串,则会导致问题。 确实,有人在第一个链接的视频中指出了这一点,对此的回应是
正确,解决方案是将您的字母映射到自然数,并向上移动所需的哨兵数量。 这样一来,您就可以始终在[1,N]值和高于该值的字母之间使用前哨。 此技巧使后缀数组可伸缩,但是您需要撤消移位,以解码存储在后缀数组中的真实值。
我不明白答案的意思。
我知道我可以在视频中发布我的问题,但是我不能保证(及时)答复,并且这里的观众范围更广,所以我想问一下这里的人 :有人可以解释一下这个答案的含义和实现方式吗?
不知道如何比引用的注释更好/不同地解释它。 也许一个例子会有所帮助。 请注意,由于我不想显示约100个源字符串的示例,因此我在这里没有使用真正的ASCII码。 因此,我们只假设A = 1,B = 2,C = 3等。
因此,您的源字符串abca bcad daca
会转换为[1,2,3,1],[2,3,1,4],[4,1,3,1]
,但为了适合三个前哨,您必须将所有这些值上移3,即1到3现在是前哨,A = 4,B = 5,等等。 连接的“字符串”(实际上现在是整数列表)是[4,5,6,4, 1, 5,6,4,7, 2, 7,4,6,4, 3]
。 然后,您可以将其转换回字符defda...
,执行算法,然后转换回,以消除偏移。
但是,我认为,与其转移的整数,我们也可以同样使用负数的哨兵,然后直接整数列表上工作,而不是将这些回字符(这是不可能的负数): [1,2,3,1, -1, 2,3,1,4, -2, 4,1,3,1, -3]
(注意:我没有看过视频,也不知道这种特定算法起作用;可能是负数是个问题,例如,如果使用某种“最短路径”算法。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.