话不多说先上干货
输出pat在str中第一次出现的位置
kmp算法最最精髓的地方在于next数组
很多人理解不了next怎么算的
在这里我说下我对next数组的理解
首先 1、next数组是完全面向pat的和str无关
2、并且next的大小和pat的长度一样
最重要的是
令 若存在一个尽可能大的k使得:
pat[ 0 到 k ] == pat[ j-k 到 j ] 那么 next[ j+1 ] 的值就为 k +1
好好理解下这句话再结合别的博主给的基础理解,就能理解完美理解kmp了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
using namespace std;
void getnext(int *next, string pat) {
int len = pat.length();
next[0] = -1;
int j = 0;
int k = -1;
while (j < len - 1) {
if (k == -1 || pat[j] == pat[k]) {
++j;
++k;
//多考虑了一步 next数组本就是当t[i]与p[j]不相等的时候对j进行改变
//而如果改变的值与当前值它们所对应的字符一样的话 那么就没有意义了
while (k != -1 && pat[j] == pat[k]) {
k = next[k];
}
if (k == -1)k++;
next[j] = k;
} else {
k = next[k];
}
}
}
int search(string str, string pat, int *next) {
int i = 0;
int j = 0;
int lenstr = str.length();
int lenpat = pat.length();
while (i < lenstr && j < lenpat) {
if (j == -1 || str[i] == pat[j]) {
i++;
j++;
} else {
j = next[j];
}
}
if (j == lenpat) return i - j;
return -1;
}
int main() {
string str, pat;
//在str中寻找pat
cin >> str >> pat;
int next[200];
getnext(&next[0], pat);
int index = search(str, pat, &next[0]);
if (index != -1) {
printf("%d\n", index);
} else {
printf("NONE\n");
}
}