C++
$\color{#cc33ff}{— > 算法基础课题解}$
思路:
KMP
$模板题$
$图解:$
时间复杂度:$O(n)$
#include<iostream>
using namespace std;
const int N = 1e5 + 10, M = 1e6 + 10;
int n, m;
char p[N], s[M];
int ne[N]; // next在某些头文件里被用过,可能会报错,所以用ne
int main(){
cin >> n >> p + 1>> m >> s + 1;
//求next的过程(next:最大的前缀和后缀相等的长度)
for (int i = 2, j = 0; i <= n; i ++){
while (j && p[i] != p[j + 1]) j = ne[j];
if (p[i] == p[j + 1]) j ++;
ne[i] = j;
}
//KMP匹配过程
for (int i = 1, j = 0; i <= m; i ++){
while (j && s[i] != p[j + 1]) j = ne[j]; //只要j没有被退回起点并且s[i]和p[j + 1]不匹配了
if (s[i] == p[j + 1]) j ++;//如果它们已经匹配,那么j可以移动到下一个位置了
if (j == n){
//匹配成功
cout << i - n << ' ';
j = ne[j];
}
}
return 0;
}