[英]Given string s, find the shortest string t, such that, t^m=s
给定字符串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的除数。 可以更有效地完成吗?
这是计算字符串周期的问题。 Knuth,Morris和Pratt的顺序字符串匹配算法是一个开始的好地方。 这是1977年题为“字符串中的快速模式匹配”的论文。
如果你想了解它,那么请查看Breslauer和Galil在1991年发表的论文“并行发现所有句号和初始回文”。从他们的摘要中:
给出了用于计算字符串的所有周期的最佳O(log log n)时间CRCW-PRAM算法。 以前的并行算法只有在短于字符串长度的一半时才计算周期。 该算法可用于在同一时间和处理器范围内查找字符串的所有初始回文。 两种算法在一般字母表中都是最快的。 我们通过修改先前已知的下限找到一个字符串的周期来得到一个寻找回文的下界[3]。 当p处理器可用时,边界变为\\ Theta(dnpe + log log d1 + p = ne 2p)。
是的,你可以在O(|s|)
时间内完成。
您可以在O(n+m)
时间内在长度为m
的“源”字符串中搜索长度为n
的“目标”字符串。 基于此构建解决方案。
让源和目标都是s
。 另一个约束是1和源中不分割|s|
任何位置 不是比赛的有效起始位置。 当然搜索本身总是会失败。 但是如果有部分匹配且你已经到达了sourse字符串的末尾,那么你就可以解决原始问题。
我真的很喜欢这种称为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
可以缩减为原始字符串。 但是,当然,如果你不想要这样的比赛,那就去看看除数。
对Boyer-Moore的修改可能在O(n)中处理这个问题,其中n是s的长度
http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.