一、原理
KMP 算法详解 - 知乎 (zhihu.com)
二、代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class KMP {
private:
vector<vector<int>> dp;
string pat;
public:
KMP(string pat){
this->pat = pat;
int M = pat.length();
// dp[状态][字符] = 下个状态
dp.resize(M, vector<int>(256, 0));
dp[0][pat[0]] = 1;
// 影子状态 X 初始为 0
int X = 0;
for (int j = 1; j < M; j++) {
for (int c = 97; c < 100; c++) {
//cout << "dp[0][pat[" << j << "]]: " << dp[0][pat[j]] << endl;
if (pat[j] == c)
dp[j][c] = j + 1;
else
dp[j][c] = dp[X][c];
//cout << "dp[" << j << "][" << c << "]: " << dp[j][c] << endl;
}
// 更新影子状态
X = dp[X][pat[j]];
//cout << "dp[" << X << "][pat[" << j << "]]: " << dp[X][pat[j]] << endl;
//cout << "X: " << X << endl;
}
}
int search(string& txt) {
int M = pat.length();
int N = txt.length();
// pat 的初始态为 0
int j = 0;
for (int i = 0; i < N; i++) {
// 当前是状态 j,遇到字符txt[i]
// pat应该转移到哪个状态?
j = dp[j][txt[i]];
// 如果达到终止态,返回匹配开头的索引
if (j == M)
return i - M + 1;
}
// 没达到终止态,匹配失败
return -1;
}
};
int main() {
string pattern = "ababc";
string text = "aaababaaababc";
KMP kmp(pattern);
int index = kmp.search(text);
if (index != -1) {
cout << "ababc found at index " << index << endl;
} else {
cout << "ababc not found." << endl;
}
return 0;
}