#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int* next(const char* cpPartten,int iParttenSize);
int kmp(const char* cpTarget,const char* cpPartten);
void main()
{
char* cpTarget=NULL;
char* cpPartten=NULL;
int answer=0;
cpTarget=malloc(200);
cpPartten=malloc(20);
printf("Target:");
scanf("%s",cpTarget);
fflush(stdin);
printf("Partten:");
scanf("%s",cpPartten);
answer=kmp(cpTarget,cpPartten);
free(cpTarget);
free(cpPartten);
}
int* next(const char* cpPartten,int iParttenSize)
{
//准备工作
int i=0,j=0;
int* iNext=NULL;
if(iParttenSize<1)
return iNext;//error
iNext=malloc(sizeof(int)*iParttenSize);
//易知
iNext[0]=-1;
if(iParttenSize!=1)
if(cpPartten[0]==cpPartten[1])
iNext[1]=-1;
else
iNext[1]=0;
//分情况讨论
i=1;
j=iNext[i];
while(i<iParttenSize-1)
{
if(cpPartten[j]==cpPartten[i])
{
iNext[i+1]=iNext[i]+1;
}
else
{
j=iNext[j];
if(j==-1)
iNext[i+1]=0;
else
continue;
}
i++;
j=iNext[i];
if(cpPartten[j]==cpPartten[i])
iNext[i]=iNext[j];
}
return iNext;
}
int kmp(const char* cpTarget,const char* cpPartten)
{
int iTargetSize=0,iParttenSize=0,i=0,j=0;
int* iNext=NULL;
iTargetSize=strlen(cpTarget);
iParttenSize=strlen(cpPartten);
iNext=next(cpPartten,iParttenSize);
if(iNext==NULL)
return -2;//error
while(iTargetSize>=iParttenSize && i<=iTargetSize)
{
if(cpTarget[i]==cpPartten[j])
{
if(j==iParttenSize-1)
return i-(iParttenSize-1);
i++;
j++;
}
else
{
if(iNext[j]==-1)
{
i++;
j=0;
continue;
}
j=iNext[j];
}
}
free(iNext);
return -1;//no matching
}
感觉高中学的数学真心是有作用的,它教会我们处理问题。先易后难,这是化难为易的好方法。
建议初学KMP算法的同学(因人而异,自选对有用的,我的不一定适合你):
1、对于用惯C的同学,不要看到讲解时从1开始对串编号而感觉不舒服。先懂过程,最后最后的结果不过是把你学的结果-1而已。
2、书上不一定能看懂,上网上找找答案。网上很多都是讲自己认识的过程,这很有帮助。
3、一时半会看不懂先放下,没准过一会灵光一闪就懂了呢,但不要放弃。
我就不说我怎么懂这玩意儿了,网上有很多。