求模式串strM的next数组
遍历比较待匹配的字符串strN(过程=遍历strN+遍历时出现strM[j]的回跳)
比较strN[i]、strM[j]时可能出现的情况为:
2.1 当前字符匹配时,同时移动 i++,j++
2.2 当前字符不匹配,且j=0时,只移动 i++,j=0不动
2.3 当前字符不匹配,且j!=0时,i不变,strM[j]回跳,当前strN[i]时最多回跳j次
如果j等于了字符串长度,就得出了一个答案,并且 j=ne[j]。
#include<iostream>
using namespace std;
const int N = 100010;
const int M = 1000010;
char s[M], p[N];
int ne[N];
int main()
{
int n, m;
scanf("%d%s%d%s", &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)
{
printf("%d ", i - n);
j = ne[j];
}
}
}