请使用C++语言并KMP算法帮我解答这道题:给定一个非空的字符串 s 检查是否可以通过由它的一个子串重复多次构成
原字符串。
C++代码如下:
#include <iostream>
#include <vector>
using namespace std;
vector<int> getNext(string p) {
int n = p.size();
vector<int> next(n, -1);
int j = -1;
for (int i = 1; i < n; i++) {
while (j >= 0 && p[i] != p[j + 1]) {
j = next[j];
}
if (p[i] == p[j + 1]) {
j++;
}
next[i] = j;
}
return next;
}
bool repeatedSubstringPattern(string s) {
vector<int> next = getNext(s);
int n = s.size();
int len = n - 1 - next[n - 1];
return len != n && n % len == 0;
}
int main() {
string s = "abab";
if (repeatedSubstringPattern(s)) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
return 0;
}
首先,我们需要实现 KMP 算法中的 getNext 函数,用于计算模式串的 next 数组。然后,我们可以通过 next 数组计算出最短的循环节长度 len,如果字符串长度 n 不等于 len,并且 n 能被 len 整除,那么原字符串可以由一个子串重复多次构成,否则不能。
对于时间复杂度,KMP 算法的时间复杂度为 O(m+n),其中 m 和 n 分别为模式串和文本串的长度。在本题中,我们只需要执行一次 KMP 算法,因此总时间复杂度为 O(n)。
原文地址: http://www.cveoy.top/t/topic/bnfc 著作权归作者所有。请勿转载和采集!