对this question的回答引用了Crochemore和Rytter的“文本算法”的第340页,该文本用于线性时间算法来计算字符串的周期。但是,它非常复杂,下面的代码是根据双向算法(由Chrochemore和Perrin编写)使用的最大后缀算法改编而成,对于计算周期似乎是正确的:
size_t period_of(const char *x)
{
size_t j=1, k=0, p=1;
while (x[j+k]) {
if (x[j+k] != x[k]) {
j += k?k:1; // Previously: j += k+1;
k = 0;
p = j;
} else if (k != p) {
k++;
} else {
j += p;
k = 0;
}
}
return p;
}
从其改编的《双向》中的版本计算出最大后缀的周期,这是计算最大后缀的副作用。但是,除非我缺少什么,否则逻辑的有效性似乎并不取决于最大后缀属性。
以上是否正确?如果没有,您能否提供一个显示失败之处的反例?
答案 0 :(得分:0)
即使在修复后,也有一个反例:
aabaaaba
在位置3,该算法首先开始匹配3期匹配的前缀。但是,当它在位置5获得a
而不是b
时,会错误地将候选时间段增加到5,从而错过了实际时间段4。
“双向”算法的改编自该算法,该算法计算最大后缀的周期,这是查找最大后缀的副作用,确实依赖于最大后缀属性。它具有!=
和>
这两个条件,而不是<
条件,其中两个条件之一将替换候选后缀的开始,另一个条件将延长运行时间。非严格地说,不会出现上述情况,因为b > a
(在这种情况下,后缀将从b
开始,或者a > b
,在这种情况下,{{1})开始}。我怀疑更详细地阅读本文(这需要使用基于一个的索引来破译其可怕的伪代码表示法)才能使其余部分变得清晰。
不幸的是,我相当确信我所询问的算法不可恢复。
还要注意,在示例中,aaa > aab
不必是单个字符。它可以是任意长的模式。这似乎排除了任何琐碎的线性时间修正。