#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
string a,b;//a为被搜索字符串,b为指定字符串。
int Nexte[5000];
int Next[5001];
void makeNext()
{
Nexte[0] = 0;
for (int star = 1, k = 0; star < b.length(); ++star)
{
while(k > 0 && b[star] != b[k])
k = Nexte[k-1];
if (b[star] == b[k])
k++;
Nexte[star] = k;
}
//求出前i个字符子串前缀与后缀最长的序列数。Nextval的求法
Next[0] = -1;
for(int i = 1; i < b.length() ; i ++)
Next[i] = Nexte[i-1];
//为了得到真正的Next序列,将Nextval右移动一位,然后将数组第一个元素改为-1.
}
int KMP()//KMP算法,寻找是否存在指定字符串,并返回数组下标。
{
int i = 0 ;
int j = 0;
int lena = a.length();
int lenb = b.length();
while(i < lena && j < lenb)
{
if(j == -1 || a[i] == b[j])
{
i ++ ;
j ++;
}
else
j = Next[j];
}
if(j == lenb)
return i-j;
else
return -1;
}
int main(void)
{
cin>>a>>b;
makeNext();
cout<<KMP()<<endl;
}
https://www.bilibili.com/video/av3246487?t=694 这个视频对KMP算法的实现过程,讲解的非常好。