#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
#define maxSize 99
//所有字符串从下标1开始存储
typedef struct
{
char *ch;
int length;
}Str;
void getnext(Str substr,int next[])
{
int i=1,j=0;
next[1]=0;
while(i<substr.length)
{
if(j==0||substr.ch[i]==substr.ch[j])
{
++i;
++j;
next[i]=j;
}
else
j=next[j];
}
}
int KMP(Str str,Str substr,int next[])
{
int i=1,j=1;
while(i<=str.length&&j<=substr.length)
{
if(j==0||str.ch[i]==substr.ch[j])
{
++i;
++j;
}
else
j=next[j];
}
if(j>substr.length)
return i-substr.length;
else
return 0;
}
int main()
{
int next[maxSize];
Str str,substr;
str.ch=(char*)malloc(sizeof(char)*maxSize);
substr.ch=(char*)malloc(sizeof(char)*maxSize);
cin>>str.ch;
str.length=strlen(str.ch)-1;//减去下标为0的字符
cin>>substr.ch;
substr.length=strlen(substr.ch)-1;
cout<<KMP(str,substr,next);
}
next 数组的改进:
void getnext(Str substr,int next[])
{
int i=1,j=0;
next[1]=0;
while(i<substr.length)
{
if(j==0||substr.ch[i]==substr.ch[j])
{
++i;
++j;
if(substr.ch[i]!=substr.ch[j])
next[i]=j;
else
next[i]=next[j];
}
else
j=next[j];
}
}
求子串在主串中出现的次数:
不考虑子串重叠,例如:主串 abbba 中,子串 bb 出现一次
int KMP(Str str,Str substr,int next[])
{
int i=1,j=1,sum=0;
while(i<=str.length)
{
if(j==0||str.ch[i]==substr.ch[j])
{
++i;
++j;
}
else
j=next[j];
if(j>substr.length)
{
j=1;
++sum;
}
}
return sum;
}