string - 等于后缀的前缀数

标签 string algorithm suffix

我试图在长度为 n 的字符串中找到等于后缀的前缀数及其长度。它们可以重叠,例如,如果字符串是“abacaba”,则 ans 是长度为 1 (a) 的 {1, 3, 7} 前缀,3 是“aba”和整个字符串。前缀“a”等于后缀“a”。前缀“aba”等​​于后缀“aba”。整个字符串等于后缀。 如果字符串是“aaaaa”,那么答案是{1, 2, 3, 4, 5}。 “a”、“aa”、“aaa”、“aaaa”、“aaaaa”。

我只能在 O(n2) 中获得,其中我们采用每个前缀并与相同长度的后缀进行比较。但是有没有更好的算法来解决这个问题呢?提前致谢

最佳答案

我的方法需要 O(N) 时间来预处理字符串,然后 O(|ans array|) 来计算答案。

预处理基本上是 KMP 故障表构建部分,在除最后一个字符外的整个字符串上。 (“abacab” 在您的示例中)。在之前返回的表中,给定字符串中最后一个索引的值(即 5'b')将为 2。这意味着与以“b”结尾的 AND 匹配的最大前缀为 2。现在,如果您的最后一个字符与前缀的第 3 个字符 ('a') 匹配,则您的后缀等于前缀。 ("aba")

KMP 停在那里。但是你想要所有的比赛。因此,您需要找到前缀以“b”结尾的所有匹配项,而不是以最后一个字符结尾的最大匹配项('b' 中的 2 个)。因此,您继续进入 KMP 的内部循环,并且像上面一样,检查当前以“b”结尾的匹配项数量(可以为零),如果下一个字符等于我们的最后一个字符。

def build_table(pat):
    table = [0]*len(pat)
    p = 0
    for i in range(1,len(pat)):
        while p>0 and pat[p]!=pat[i]: #KMP's loop i was talking about
            p = table[p-1]

        if pat[p]==pat[i]:
            table[i] = p+1
            p+=1

    return table

pat = "abracadabab"
table = build_table(pat[:-1]) #build table for "abracadaba", i.e except last 

ans = [] #to store answers
p = len(pat)-1 #last index of table building string i.e 5 or 'b'
while p>0: #the main loop
    p = table[p-1] 
    print(p)
    if pat[p]==pat[-1]:
        ans.append(p+1)

print(ans)

"abacab" 打印 [1,3]"abracadabra" 打印 [1,4]。将整个长度视为特例。

(注意我的 while 循环和 KMP 循环之间的相似性。如果您仍然感到困惑,我强烈建议您彻底阅读/理解 KMP。很容易对它有一个整体的了解,但深入理解对于回答这样的问题真的很难而且至关重要。)

关于string - 等于后缀的前缀数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47224030/

相关文章:

Java正则表达式匹配除可选后缀之外的贪婪数据

重命名列名称的后缀部分,但保持其余部分相同

c - fgets() 与 realloc() 的奇怪行为

python - 我如何告诉 python 整个值是一个字符串?因为我的Excel公式中有撇号

c# - 获取单词或数字的所有排列

c - 将新节点放入二叉树堆中的下一个可用位置?

java - 在包含 2 个指定顶点的无向图中查找最短循环

python - 查找列表/文件中以特定前缀/后缀开头/结尾的所有单词

java - 如何在android中实用地在不同语言字符串资源文件夹之间切换?

java - 空字符串测试始终为真