字符串操作:计算“字符串与其后缀的相似性”

时间:2011-12-15 19:44:42

标签: string algorithm

对于两个字符串A和B,我们将字符串的相似性定义为两个字符串共有的最长前缀的长度。例如,字符串“abc”和“abd”的相似性为2,而字符串“aaa”和“aaab”的相似度为3。

问题是给出一个算法来计算字符串S与每个后缀的相似之和。例如,让字符串为:ababaa。然后,字符串的后缀为ababaababaaabaabaaaaa。这些字符串中的每一个与字符串ababaa的相似性分别为6,0,3,0,1,1。因此答案是6 + 0 + 3 + 0 + 1 + 1 = 11

2 个答案:

答案 0 :(得分:9)

您想要考虑suffix arrays。单词的后缀数组是按字典顺序排序的后缀索引的数组。在链接的维基百科文章中,算法在计算后缀数组时计算LCP(最长公共前缀)。您可以使用与suffix trees相似的内容在O(n)中进行计算,如this paper所示。

示例:您的字符串是ababaa,因此后缀数组如下所示:

5 | a
4 | aa
2 | abaa
0 | ababaa
3 | baa
1 | babaa

其中左边的数字是后缀开始的索引。现在每个计算前缀都非常好,因为所有内容都是按字典顺序存储的。

作为旁注,这与longest common substring问题密切相关。为了练习下一次面试,请考虑如何有效地解决这个问题。

答案 1 :(得分:0)

首先阅读有关z-algorithm的链接。 一个基于python实现的链接中基于算法的O(n)解决方案:

def z_func(s):
    z = [0]*len(s)
    l, r = 0, 0
    for i in range(1,len(s)):
        if i<=r:
            z[i] = min(r-i+1, z[i-l])
        while (i + z[i] < len(s) and s[z[i]] == s[i + z[i]]):
            z[i] += 1
        if z[i]+i-1 > r:
            l, r = i, z[i]+i-1
    return sum(z)+len(s)