给定字符串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的除数。可以更有效地完成吗?
答案 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