前言
这个算法还是比较难的,看了好多视频才搞明白 ,主要还是next数组,我们来讲解一下。
kmp
题目
next数组
for (int i = 2, j = 0; i <= n; i++)
{
while (j && p[i] != p[j + 1])//如果不等于 就回到ne[j]
j = ne[j];
if (p[i] == p[j + 1])//成立就j++
j++;
ne[i] = j;//他的next是j
}
比如这个s: 他先和t比 不等于, j=a[1],还是不等于b ,那j=0,退出,s的下面就是0
因为s的前一项肯定和ne【j】相等所以可以和数组算前缀的数量。
这个倒数第二个a:他先发现不等于,就等于j=2比,发现p[i]==p[j+1]也就是3,所以是3
完整代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100005, M = 100005;
int n, m;
char p[N], s[N];
int ne[N];
int main()
{
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 - n <<' ';
j = ne[j];
}
}
return 0;
}
总结
kmp是一个需要好好思考的代码,我认为还是很有难度的,所以要牢牢理解,特别是next数组。