无法理解http://pine.cs.yale.edu/pinewiki/SuffixArrays中提到的概念

时间:2012-08-13 09:18:34

标签: string algorithm search suffix-array

请解释:

  

假设我们有一个对应于n字符文本的后缀数组,我们想要在m字符模式的文本中找到所有出现的内容。由于后缀是有序的,最简单的解决方案是使用O(log n)比较对模式的第一次和最后一次出现(如果有的话)进行二进制搜索。

在确定模式的第一次和最后一次出现后,我需要知道如何才能获得所有出现的模式。

1 个答案:

答案 0 :(得分:1)

你引用的文字有两点令人困惑,甚至可能有误导性:

  1. 它说找到模式的第一个和最后一个出现就足够了,但应该更准确地说:后缀数组中的第一个和最后一个出现。这与基础文本中第一次和最后一次出现的情况不同。

  2. 它说你需要进行O(log n)比较。仅当“比较”指的是最多m个字符的字符串比较时,才会出现这种情况。由于比较多达m个字符需要O(m)时间,因此计算步骤的数量(例如在标准RAM模型中)是O(m * log n)。如果构建和使用辅助数据结构,例如LCP(最长公共前缀)数组,则可以改进它。

  3. 现在,回答您的问题:考虑上面的(1.),您可以轻松地获得所有模式,因为后缀数组按字典顺序排序。这意味着第一次出现的是字典上最小的,最后出现的是字典上最大的。因此,剩余的事件必须介于之间的第一个和最后一个。

    示例。考虑字符串bcfabcabxbbcabcgdebcd。它的后缀数组(表示为后缀的起始位置,从0开始计数)是

    [3, 12, 6, 9, 10, 4, 18, 0, 13, 7, 11, 5, 19, 1, 14, 20, 16, 17, 2, 15, 8]
    

    对应于以下后缀列表:

    3  : abcabxbbcabcgdebcd
    12 : abcgdebcd
    6  : abxbbcabcgdebcd
    9  : bbcabcgdebcd
    10 : bcabcgdebcd            <======= first occurrence of 'bc'
    4  : bcabxbbcabcgdebcd
    18 : bcd
    0  : bcfabcabxbbcabcgdebcd
    13 : bcgdebcd               <======= last occurrence of 'bc'
    7  : bxbbcabcgdebcd
    11 : cabcgdebcd
    5  : cabxbbcabcgdebcd
    19 : cd
    1  : cfabcabxbbcabcgdebcd
    14 : cgdebcd
    20 : d
    16 : debcd
    17 : ebcd
    2  : fabcabxbbcabcgdebcd
    15 : gdebcd
    8  : xbbcabcgdebcd
    

    假设您要寻找的模式是'bc'。我在后缀数组中标记了该模式的第一次和最后一次出现。由于词典排序,其间的所有条目也必须以'bc'开头,任何以'bc'开头的条目必须介于两者之间。因此,所有以'bc'开头的后缀,即'bc'出现的所有位置,必须介于第一次和最后一次出现之间。

    表示为位置整数,我们确定的范围是

    [10, 4, 18, 0, 13]
    

    因此,位置10,4,18,0和13标记了模式的出现。

    (注意,实际上不使用后缀的完整字符串列表 - 只使用整数位置列表。)