#include<iostream>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
int n, m;
int Next[maxn]; //含义: 从第0位到第i位的字串的最大公共前后缀
char Mo[maxn], Te[maxn]; //含义: Mo是模式串,Te是匹配的串
//初始化Next数组
void init_Next() {
Next[0] = 0; //由于字串只有一位,所以没有公共前后缀
int l = 0, r = 1; //第0位已经初始化,所以r等于1
while (r < m) {
if (Mo[l] == Mo[r]) { //匹配成功说明l之前的字串也匹配成功
Next[r++] = ++l; //故Next的值为l
}
else { //不匹配的情况
if (l >= 1) { //防止越界
l = Next[l - 1];
}
else {
Next[r++] = l; //此时Next的值为0
}
}
}
}
//kmp搜索核心
void kmp_Serch() {
init_Next(); //初始化Next
int i = 0, j = 0; //i枚举Te,j枚举Mo
while (i < n) {
if (j == m - 1 && Mo[j] == Te[i]) { //如果匹配成功,就执行相应操作
printf("%d\n", i - j + 1);
if (j >= 1) j = Next[j - 1]; //j指针回溯到Next[j - 1]的位置,切记不能越界
}
if (Mo[j] == Te[i]) {
i++, j++;
}
else {
if (j >= 1) j = Next[j - 1]; //j指针回溯到Next[j - 1]的位置,切记不能越界
else i++; //j指针回溯到0,则i++,因为这种情况不可能成立了,所以i++
}
}
}
int main() {
cin >> Te >> Mo;
m = strlen(Mo);
n = strlen(Te);
kmp_Serch();
return 0;
}
模板——KMP搜索
最新推荐文章于 2024-04-15 09:55:44 发布