在单词中找到最短的重复循环?

jac*_*k44 17 language-agnostic algorithm pseudocode

我即将编写一个函数,它将返回一个最短的一组字母,最终会创建给定的单词.

例如字abkebabkebabkeb通过重复创建abkeb字.我想知道,如何有效地分析输入词,以获得创建输入词的最短字符周期.

Bug*_*uge 12

这是一个正确的O(n)算法.第一个for循环是KMP的表构建部分.有各种证据表明它总是在线性时间内运行.

由于这个问题有4个先前的答案,其中没有一个是O(n)和正确的,我严重测试了这个解决方案的正确性和运行时间.

def pattern(inputv):
    if not inputv:
        return inputv

    nxt = [0]*len(inputv)
    for i in range(1, len(nxt)):
        k = nxt[i - 1]
        while True:
            if inputv[i] == inputv[k]:
                nxt[i] = k + 1
                break
            elif k == 0:
                nxt[i] = 0
                break
            else:
                k = nxt[k - 1]

    smallPieceLen = len(inputv) - nxt[-1]
    if len(inputv) % smallPieceLen != 0:
        return inputv

    return inputv[0:smallPieceLen]
Run Code Online (Sandbox Code Playgroud)

  • 那么[KMP是一种已知的算法](https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm).这个问题与我的家庭作业问题非常相似,这就是我为家庭作业提出的答案.教练的解决方案有点不同,但也使用了KMP. (3认同)
  • @LinMa :( Buge最近没有活动)`nxt [-1]意味着如果整个字符串不匹配,我们将用什么索引来比较下一个没有(扭曲语法,顺便说一下).当所有模式匹配并且您想要在较长的文本中找到它的下一个出现时,它是下一个比较的索引.`nxt [i] = p`表示`pattern [i + 1-p:i + 1]`等于`pattern [0:p]`(&!= for`p + 1`).`nxt [-1]`是下一个比较的索引,如果"第一个"不匹配是"at`len` + 1".(在许多KMP的表示/实现中,在索引0处有一个特殊值-1,其中n值如上所述"转移到高一个索引".) (2认同)
  • @Boris 我认为 `[1, 2]` 是错误的。问题是“例如,单词‘abkebabkebabkeb’是由重复的‘abkeb’单词创建的。” 但不可能通过重复“[1, 2]”来创建“[1, 2, 1]”。您需要重复它,然后砍掉末尾以获得“[1,2,1]”。但是,是的,这个问题对于“[1,2,1]”的正确答案是什么有些含糊。 (2认同)

dfb*_*dfb 1

O(n) 解。假设必须覆盖整个字符串。关键的观察是我们生成模式并测试它,但是如果我们发现一些不匹配的东西,我们必须包含我们已经测试过的整个字符串,这样我们就不必重新观察这些字符。

def pattern(inputv):
    pattern_end =0
    for j in range(pattern_end+1,len(inputv)):

        pattern_dex = j%(pattern_end+1)
        if(inputv[pattern_dex] != inputv[j]):

            pattern_end = j;
            continue

        if(j == len(inputv)-1):
            print pattern_end
            return inputv[0:pattern_end+1];
    return inputv;
Run Code Online (Sandbox Code Playgroud)

  • 恐怕算法不正确。请考虑输入:“BCBDBCBCBDBC”。最小的重复模式是“BCBDBC”,但上面的算法会错过它。另外,我认为它不能正确处理“HELLOHELL”的情况(它返回“HELLO”而不是完整的字符串)。 (12认同)
  • @Boris:问题是找到 S 的最小子序列,使得 K>=1 重复它会导致 S 本身。输入“HELLOHELL”没有K>1的重复子序列,因此应返回“HELLOHELL”。 (2认同)