学了那么久KMP。今天才有那么一点点的懂~~囧。。next数组的得来还真心不是很懂啊~~~不过就是知道利用递归的思想,由下往上推,总而得出前缀后缀的最大相等长度,不过又有点回溯的思想,还好像有点递推的思想,因为后面的next数组的结果和前面的next数组的值是紧密相关的额~~
下面贴模板,直接数组下标从一开始的
program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;
int len1,len2;
char a[5000000],b[5000000],aa[5000000],bb[5000000];
int next[5000000];
void get_next()
{
int i=1,j=0;
next[1]=0;
while(i<len2)
{
if(j==0||bb[i]==bb[j]){ ++i; ++j; next[i]=j; }
else j=next[j];
}
}
int kmp()
{
int i=1,j=1;
while(i<=len1&&j<=len2)
{
if(j==0||aa[i]==bb[j]){ ++i; ++j; }
else j=next[j];
}
if(j>len2)return i-len2;
return 0;
}
int main()
{
while(cin>>a>>b)
{
len1=strlen(a);
len2=strlen(b);
for(int i=1;i<=len1;i++)
{
aa[i]=a[i-1];
}
for(int i=1;i<=len2;i++)///
{
bb[i]=b[i-1];
}
get_next();
int tmp=kmp();
if(tmp)
cout<<"yes "<<tmp<<endl; 返回的是子串在母串的开始位置
else
cout<<"not found"<<endl;
}
return 0;}
顺便把朴素的字符串子串查找贴上去
program2:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;
int len1,len2;
char a[5000000],b[5000000],aa[5000000],bb[5000000];
int index()
{
int i=1,j=1;
while(i<=len1&&j<=len2)
{
if(j==0||aa[i]==bb[j]){ ++i; ++j; }
else {i=i-j+2;; j=1; }
}
if(j>len2)return i-len2;
return 0;
}
int main()
{
while(cin>>a>>b)
{
len1=strlen(a);
len2=strlen(b);
for(int i=1;i<=len1;i++)
{
aa[i]=a[i-1];
}
for(int i=1;i<=len2;i++)///
{
bb[i]=b[i-1];
}
int tmp=index();
if(tmp)
cout<<"yes "<<tmp<<endl;
else
cout<<"not found"<<endl;
}
return 0;}