字符串_kmp算法
kmp算法的核心就是pi数组,pi[i]所表示的是在字符串s的子串s[0-i]中,最长的真前缀与后缀相等的长度。
pi数组的求法:
点击查看代码
vector<int> pi(n);
for (int i = 1; i < n; i++) {
int j = pi[i - 1];
while (j > 0 && s[i] != s[j]) {
j = pi[j - 1];
}
if (s[i] == s[j]) {
j++;
}
pi[i] = j;
}
点击查看代码
int bin = n;
vector<int> pre;
pre.push_back(n);
while (bin) {
if (!pi[bin - 1])
break;
pre.push_back(pi[bin - 1]);
bin = pi[bin - 1];
}
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s;
cin >> s;
int n = s.size();
// cout << s << ' ' << n;
vector<int> pi(n);
for (int i = 1; i < n; i++) {
int j = pi[i - 1];
while (j > 0 && s[i] != s[j]) {
j = pi[j - 1];
}
if (s[i] == s[j]) {
j++;
}
pi[i] = j;
}
int bin = n;
vector<int> pre;
pre.push_back(n);
while (bin) {
if (!pi[bin - 1])
break;
pre.push_back(pi[bin - 1]);
bin = pi[bin - 1];
}
cout << pre.size() << "\n";
vector<int> cnt(n + 1);
for (int i = 0; i < n; i++) {
cnt[pi[i]]++;
}
for (int len = n; len > 0; len--) {
cnt[pi[len - 1]] += cnt[len];
}
for (int i = pre.size() - 1; i >= 0; i--) {
cout << pre[i] << ' ' << cnt[pre[i]] + 1 << "\n";
}
return 0;
}
浙公网安备 33010602011771号