#include<iostream>
#include<cstring>
using namespace std;
#define N 100
int next[N]={-1};//-1表示到该位置的串,前缀后缀的最大相等长度是next[i]+1
void cal_next(string ptr) //计算next数组
{
int i,j,k=-1;
for(i=1;i<ptr.length();i++)
{
while(k>-1&&ptr[k+1]!=ptr[i])
{
// 往前回溯 ,程序的意思是说 一旦ptr[k + 1] != ptr[i],即在后缀里面找不到时,我是可以直接跳过中间一段,跑到前缀里面找
}
if(ptr[k+1]==ptr[i])
{
k++;
}
next[i]=k;
}
for(j=0;j<ptr.length();j++)
{
cout<<next[j]<<" ";
}
cout<<endl;
}
int kmp(string str,string ptr)
{
int k=-1;
cal_next(ptr);
for(int i=0;i<str.length();i++)
{
while(k>-1&&str[i]!=ptr[k+1])
{
k=next[k];
}
if(str[i]==ptr[k+1])
k++;
if(k==ptr.length()-1)
{
return i-ptr.length()+1;
}
}
return -1;
}
int main()
{
string str="bacbababadababacambabacaddababacasdsd";
string ptr= "ababaca";
cout<<kmp(str,ptr)<<endl;
return 0;
}
#include<cstring>
using namespace std;
#define N 100
int next[N]={-1};//-1表示到该位置的串,前缀后缀的最大相等长度是next[i]+1
void cal_next(string ptr) //计算next数组
{
int i,j,k=-1;
for(i=1;i<ptr.length();i++)
{
while(k>-1&&ptr[k+1]!=ptr[i])
{
k=next[k];
}
if(ptr[k+1]==ptr[i])
{
k++;
}
next[i]=k;
}
for(j=0;j<ptr.length();j++)
{
cout<<next[j]<<" ";
}
cout<<endl;
}
int kmp(string str,string ptr)
{
int k=-1;
cal_next(ptr);
for(int i=0;i<str.length();i++)
{
while(k>-1&&str[i]!=ptr[k+1])
{
k=next[k];
}
if(str[i]==ptr[k+1])
k++;
if(k==ptr.length()-1)
{
return i-ptr.length()+1;
}
}
return -1;
}
int main()
{
string str="bacbababadababacambabacaddababacasdsd";
string ptr= "ababaca";
cout<<kmp(str,ptr)<<endl;
return 0;
}