#include <iostream>
#include <string>
using namespace std;
// 构建KMP的next数组
void getNext(const string& t, int next[]) {
int len = t.size();
next[0] = -1;
int j = 0, k = -1;
while (j < len - 1) {
if (k == -1 || t[j] == t[k]) {
j++;
k++;
next[j] = k;
} else {
k = next[k];
}
}
}
// 利用KMP算法统计子串t在主串s中不重叠出现的次数,并显示匹配过程
int countKMPNonOverlap(const string& s, const string& t) {
int sLen = s.size();
int tLen = t.size();
if (sLen < tLen) return 0;
int next[tLen];
getNext(t, next);
int count = 0;
int i = 0; // 主串指针
while (i <= sLen - tLen) {
int j = 0; // 子串指针
// 显示当前匹配的主串起始位置(方便查看过程)
cout << "当前主串起始位置: " << i << ",待匹配子串: " << t << endl;
// KMP匹配过程
while (j < tLen && s[i + j] == t[j]) {
j++;
}
if (j == tLen) {
// 匹配成功,计数+1,主串指针跳转子串长度(避免重叠)
count++;
cout << "匹配成功!位置: " << i << "~" << i + tLen - 1 << endl;
i += tLen;
} else {
// 匹配失败,根据next数组调整主串指针
if (next[j] == -1) {
i++;
} else {
i += (j - next[j]);
}
}
}
return count;
}
int main() {
string s = "aaabbdaabbd";
string t = "aabbd";
cout << "主串s: " << s << endl;
cout << "子串t: " << t << endl;
cout << "----------------匹配过程----------------" << endl;
int result = countKMPNonOverlap(s, t);
cout << "----------------匹配结果----------------" << endl;
cout << "子串t在主串s中不重叠出现的次数: " << result << endl;
return 0;
}