#include<iostream>
#include<string>
using namespace std;
int* KmpNext(string str) {
int* next = new int[str.size()];
next[0] = 0;
for (int j = 1, k = 0; j < str.size(); ++j) {
while (k > 0 && str[k] != str[j]) {
k = next[k - 1];
}
if (str[j] == str[k]) {
++k;
}
next[j] = k;
}
return next;
}
int KMP(string s, string t, int* next) {
// s主串 t 模式串
for (int i = 0, j = 0; i < s.size(); ++i) {
while (j > 0 && s[i] != t[j]) {
j = next[j - 1]; // 下一个匹配位是next的第j-1位
}
if (s[i] == t[j]) {
++j; // 主串通过i+1, 模式串通过j+1
}
if (j == t.size()) {
return i - j + 1; // 返回匹配位置
}
}
return -1;
}
void PrintNext(string s) {
cout << "***********************************" << endl;
int* nextI = nullptr;
nextI = KmpNext(s);
cout << "模式串: '" + s + "' 的next[]数组为[";
for (int i = 0; i < s.size(); ++i) {
cout << *(nextI + i) << " ";
}
cout << "]" << endl;
cout << "模式串长度为: " + to_string(s.size()) + " " << endl;
}
int main() {
string s = "CDFGFABABAFABABAAAQWEDC";
string t = "ABABAA";
int* next = KmpNext(t);
int res = KMP(s, t, next);
if (res != -1) {
cout << "起始位置为: " + to_string(res) + " " << endl;
}
else {
cout << "主串中不包含字符串: " + t << endl;
}
PrintNext("ABCDABD");
PrintNext("ABABAA");
PrintNext("ABAABCAC");
return 0;
}
结果
起始位置为: 11
***********************************
模式串: 'ABCDABD' 的next[]数组为[0 0 0 0 1 2 0 ]
模式串长度为: 7
***********************************
模式串: 'ABABAA' 的next[]数组为[0 0 1 2 3 1 ]
模式串长度为: 6
***********************************
模式串: 'ABAABCAC' 的next[]数组为[0 0 1 1 2 0 1 0 ]
模式串长度为: 8