下面是一些基本的C++代码,没有工作:
bool IsRepeating(std::string in) {
int totalLength = in.length();
for (int subLength = 1; subLength <= totalLength/2; subLength++) {
if (totalLength % subLength != 0) continue;
for (int startPos = 0; startPos < subLength; startPos++) {
char startChar =in[startPos];
bool mismatchFound = false;
for (int delta = subLength; delta < totalLength-startPos; delta += subLength) {
if (in[startPos+delta] != startChar) {
mismatchFound = true;
break;
}
}
if (mismatchFound) {
break;
}
return true;
}
}
return false;
}
它利用的子串长度必须总字符串长度的约数的事实。
最糟糕的时间复杂度非常糟糕,就像O(n^2 log(log(n))),但我不确定。 (最糟糕的情况是,当字符串由两个完全相同的子字符串组成时)。我仍然认为平均而言,它应该表现得相当好,因为大多数外部循环体只对字符串长度的除数执行,并且内部循环尽快中止因为发现不匹配。
编辑:@Veedrac的解决方案不仅更优雅,而且在大多数情况下也更高效。对于直接比较,这里是C++版本:
bool IsRepeating(const std::string& in) {
if (in.length() < 1) return false;
return (in + in).substr(1, 2 * in.length() - 2).find(in) != std::string::npos;
}
它确实使用更多的内存。如果您不知道该功能的用途,可能很难弄明白。但这也适用于我的原始版本。
确实有趣的问题。到目前为止,我学到的是,对于每个“正则表达式”都有一个“有限自动机”。第一个问题应该是“是否有动态模式识别的有限自动数据?”。如果是这样,比你可以将其转换为正则表达式,反之亦然。 – TheRealVira
如果支持反向引用,它可以通过正则表达式完成:'^(。+)\ 1 + $' –
解释为什么这是例子真实:abaaabaaabaa您认为重复模式是什么? –