kmp算法
给定一个模式串S以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字。
模板串P在模式串S中多次作为子串出现。
求出模板串P在模式串S中所有出现的位置的起始下标。
输入格式
第一行输入整数N,表示字符串P的长度
第二行输入字符串P
第三行输入整数M,表示字符串S的长度
第四行输入字符串M
输出格式
共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间用空格隔开
数据范围
1
≤
N
≤
1
0
4
1\le N \le 10^4
1≤N≤104
1
≤
M
≤
1
0
5
1\le M \le 10^5
1≤M≤105
输入样例
3
aba
5
ababa
输出样例
0 2
AC代码
#include<iostream>
using namespace std;
const int N = 1e5 + 10, M = 1e5 + 10;
int n, m;
char p[N], s[M];
int ne[N];
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> p + 1 >> m >> s + 1;
// 求 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 match
for(int i = 1, j = 0; i <= m; i++) {
while(j && s[i] != p[j + 1]) j = ne[j];
if(s[i] == p[j + 1]) j++;
if(j == n) {
printf("%d ", i - n);
j = ne[j];
}
}
return 0;
}