繁体   English   中英

通过后缀数组的最长公共子字符串:sentinel的使用

[英]Longest common substring via suffix array: uses of sentinel

我正在阅读有关一系列字符串中最长的公共子字符串的(显然)众所周知的问题,并且一直在关注这两个视频,它们讨论了如何使用后缀数组解决问题:(请注意,此问题不需要您观看它们):

https://youtu.be/Ic80xQFWevc

https://youtu.be/DTLjHSToxmo

第一步,我们首先将所有源字符串连接成一个大字符串,并用一个“唯一”标记来分隔每个源字符串,其中每个标记的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM