说到KMP算法就不得不说一说BF(Brute Force)算法,因为好的事情的发展和进步往往都是因为原始事物状态的低效与不足。就像世界大战时期有些大咖说过,战争是推动社会进步的主要动力!虽然文字用的比较尖锐,听起来也比较残酷,但是细想还是有一定道理,当生活被压迫的不能继续,当明天成为了一种黑暗,当自由变成一种奢望,当腐败变成一种习以为常、、、这个时候就需要改变,需要进步,也就需要战争来维护人类生活的尊严!战争的深处是罪恶,但是物极必反,就像古代的八卦图一样,阴盛阳衰,阳盛阴衰,罪恶的尽头也会出现真善美,那一抹光明!扯了这么多没用的,下面步入正题,主要是想说一下,KMP是BF的改进版,效率提高了不少。
这其中一个主要改进的地方就是指针回溯的问题,在BF算法中,之所以称为蛮力,就是因为每次比较后,指针都会回到当初的起点,比如原始字符串S,和目标串P,首先P的第一个字母和S的第一个字母进行比较,如果相等,则继续比较第二个、、、、突然第N个不相等 了,那怎么办,难道前N-1个白比较了????这也是我们做的有用功啊,不能就这么浪费,但是对于BF算法来说,这就无所谓了,我就是力气多,不怕浪费,S串的指针就直接NB的回到原始串的第二个,而T串的指针也就直接回到起始位置,再开始比较,就这样一次比较下去,找到了则返回位置,没找到就没找到,累的够呛,其实也不累,力气多!(在计算机里就是不怕花时间和空间-内存,我有的是,事实上是不可取的)所以就来了一个比较喜欢“偷懒的人”,他就在想,我能不能在比较完之后,不会到起初的原点再继续比较,多累啊,因为这些我都已经比较过了啊,为什么还要走第二遍呢,不想走已经走过的路啊,我想向前走啊,于是乎他想到了一个办法,就是KMP算法,解决了指针不回溯的问题,或者说是回溯的少的,少走两步,这样可以节约力气!
具体的分析过程,在这个博客里实在是不好表达过程,主要是求next[i]数组里的值!我就不一一赘述了,其实我相信很多人已经比我先明白了!
具体代码如下:
BF算法:
#include <stdio.h>
char S[]="kljfidfoijababakjiko";
char P[]="ababa";
int BF(char *s,char *p)
{
int i=0;
int j=0;
if(!s || !p) //空串;
return -1;
while(s[i])
{
if(p[j]=='\0') //找到;
return (i-j);
if( s[i]==p[j])
{
i++;
j++;
}
else
{
i=i-j+1;
j=0;
}
}
return -1; //没找到;
}
int main()
{
int result;
int i ;
result=BF(S,P);
printf("%s\n",S);
if(result>0)
for(i=0;i<result;i++)
printf(" ");
printf("%s\n",P);
printf("position: %d\n",result);
return 0;
}
KMP算法:
#include <stdio.h>
#include <string.h>
char par[]="ababa";
char str[]="kljfidfoijababakjiko";
int next[10];
//得到next数组的值;
int GetNext(char *par,int *next)
{
int i=0;
int k=-1;
next[0]=-1;// 这是由数组下表决定的;
if(!par)
return -1;
while(par[i])
{
if( -1==k || par[i]==par[k] )
{
i++;
k++;
if(par[i]==par[k])
{
next[i]=next[k];
}
else
{
next[i]=k;
}
}
else
{
k=next[k];
}
}
return 0;
}
int KMP(char *str,char *par,int *next)
{
int i=0;
int j=0;
if(str==NULL || par==NULL)
return -1;
while(str[i])
{
if(par[j]=='\0')
return (i-j);
if(j==0 || str[i]==par[j])
{
i++;
j++;
}
else
{
j=next[j];
}
}
return -1;
}
int main()
{
int i;
int result;
GetNext(par,next);
result=KMP(str,par,next);
printf("%s\n",str);
for(i=0;i<result;i++)
printf(" ");
printf("%s\n",par);
printf("position: %d\n",result);
for(i=0;i<(int)strlen(par);i++)
printf("%d ",next[i]);
return 0;
}
本人愚钝,领悟至此,颇有感慨,与己共勉,陋文浅显,见者海涵!