给定字符串s,找到最短的字符串t,使得t ^ m = s

时间:2011-12-01 20:26:27

标签: string algorithm

给定字符串s,找到最短的字符串t,使得t ^ m = s。

示例:

s="aabbb" => t="aabbb"
s="abab"  => t = "ab"

可以多快完成?

当然天真地,对于每m个除| s |,我可以尝试子串(s,0,| s | / m)^ m = s。

可以在O(d(| s |)n)时间内找出解,其中d(x)是s的除数。可以更有效地完成吗?

4 个答案:

答案 0 :(得分:5)

这是计算字符串周期的问题。 Knuth, Morris and Pratt's sequential string matching algorithm是一个开始的好地方。这是1977年题为“字符串中的快速模式匹配”的论文。

如果您想了解它,请查看1991年由Breslauer和Galil撰写的文章“并行查找字符串的所有句点和初始回文”。摘自:

  

用于计算全部的最佳O(log log n)时间CRCW-PRAM算法   呈现字符串的句点。以前的并行算法计算   这个时期只有短于一半的时间   串。该算法可用于查找所有初始回文   一个字符串在同一时间和处理器边界。两种算法都是   一般字母表中最快的。我们得出一个下界   通过修改先前已知的低位来找到回文   一定要找到一个字符串的句号[3]。当p处理器是   可用边界成为\ Theta(d n p e + log log d1 + p = ne 2p)。

答案 1 :(得分:2)

是的,你可以在O(|s|)时间内完成。

您可以在n时间内搜索长度为m的“来源”字符串中长度为O(n+m)的“目标”字符串。基于此构建解决方案。

让源和目标都为s。另一个约束是1和源中没有划分|s|的任何位置都不是匹配的有效起始位置。当然搜索本身总是会失败。但是如果有部分匹配且你已经到达了sourse字符串的末尾,那么你就可以解决原始问题。

答案 2 :(得分:2)

我真的很喜欢这种称为z算法的东西:http://www.utdallas.edu/~besp/demo/John2010/z-algorithm.htm

对于每个位置,它计算从那里开始的最长子串,这也是整个字符串的前缀。 (当然是线性时间)。

a   a   b   c   a   a   b   x   a   a   a   z
    1   0   0   3   1   0   0   2   2   1   0

鉴于这个“z-table”,很容易找到所有可以对整个事物进行取幂的字符串。如果pos+z[pos] = n,请检查所有职位。

在我们的案例中:

a   b   a   b
    0   2   0

此处pos = 2为您提供2+z[2] = 4 = n,因此您可以使用的最短字符串是长度为2的字符串。

这甚至可以让您找到只有指数字符串的前缀匹配的情况,例如:

a   b   c   a
    0   0   1

此处(abc)^2可以缩减为原始字符串。但是,当然,如果你不想要这样的比赛,那就过去吧。但是只需要去掉除数。

答案 3 :(得分:0)

对Boyer-Moore的修改可能在O(n)中处理这个问题,其中n是s的长度

http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm