[AcWing 831] KMP字符串


点击查看代码
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
const int M = 1e6 + 10;
int ne[N];
int main()
{
int n, m;
char p[N], s[M];
cin >> n >> p + 1 >> m >> s + 1;
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;
}
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) {
cout << i - j << ' ';
j = ne[j];
}
}
return 0;
}
- ne 数组用来记录下一次 j 应当从哪个位置开始继续匹配;
- p 和 s 都从数组下标为 1 开始存放;
- 求 ne 数组的过程:当 j 不为 0 并且 p[ i ] != p[ j + 1 ] 说明 j 应当往回退,直到 j 到达 0 或者满足前缀等于后缀的位置,如果 p[ i ] == p[ j + 1 ],则 j ++,表示下一次从后面这个位置开始匹配,最后 ne[ i ] = j 用来 ne 数组的值;
- 匹配的操作和求 ne 的操作类似,当满足 j == n 时,说明匹配成功,输出位置,并让 j = ne[ j ],注意输出的时候是 i - j + 1 - 1(i - j + 1 表示 s 数组匹配成功的起始下标,- 1 是因为定义的 s 数组是从下标为 1 开始的,而题目要求的是要从 0 开始的下标);

浙公网安备 33010602011771号