如何使用后缀数组和LCP数组找到字符串的ith子字符串?

时间:2016-06-12 14:29:00

标签: c++ string algorithm time-complexity suffix-array

如果我们按字典顺序排列字符串的所有不同子字符串,我们需要第i个子字符串

1。)是否可以使用suffix arrayLCP array找到它?

2。)如果是,我们该怎么办?可以在使用Manber& amp;创建后缀数组时在O(Nlog ^ N)中完成Myers的时间复杂度为O(Nlog ^ 2N),或者使用时间复杂度为O(N)的kasai算法创建它的LCP数组?

1 个答案:

答案 0 :(得分:2)

是的,可以使用Suffix数组和LCP阵列来完成。

假设您知道如何计算后缀数组和LCP数组。

p[]表示后缀数组lcp[]表示LCP数组。

创建一个数组,该数组存储不同子字符串的数量,直到i'th等级后缀。这可以使用此公式计算。有关详细信息,请参阅Here

cum[]表示累积数组,可以按如下方式计算:

cum[0] = n - p[0];
for i = 1 to n do:
    cum[i] = cum[i-1] + (n - p[i] - lcp[i])

现在找到i'th子字符串,只需在累积数组i中找到cum[]的下限,它将为您提供子字符串应从其开始的后缀的排名并打印所有字符<长度

i - cum[pos-1] + lcp[pos] // i lies between cum[pos-1] and cum[pos] so for finding 
                          // length of sub string starting from cum[pos-1] we should 
                          // subtract cum[pos-1] from i and add lcp[pos] as it is 
                          // common string between current rank suffix and 
                          // previous rank suffix. 

其中pos是按下限返回的值。

以上整个过程可归纳如下:

string ithSubstring(int i){
    pos = lower_bound(cum , cum + n , i);
    return S.substr(arr[pos] , i - cum[pos-1] + lcp[pos]);// considering S as original character string 
}

要完全实现后缀数组,LCP及以上逻辑,您可以看到Here