字符串匹配--KMP算法

来源:互联网 发布:网络球型摄像机 编辑:程序博客网 时间:2024/06/05 16:33

最近学了一下KMP匹配算法,这个算法在字符串匹配中还是很有名的

一般的字符串匹配算法是这样的

1.比较目标串和待匹配的字符串,一个字符一个字符的比较,如果比较到待匹配串的末尾,则返回匹配成功的位置;

2.发现有不同的停止比较,将目标串向后移动一格,待匹配字符串重新回到起点,回到步骤1,继续匹配。

这个算法的优点是思路简单,有点像排序中的冒泡排序,选择排序的样子。缺点就是有大量的重复计算。


KMP匹配算法就是为了实现减少不必要的重复计算,这个思想在很多改良的算法中都是通用的。

        例如 要寻找 pappappar 中pappar 出现的位置,按照上面的算法第一次匹配中一直匹配到pappar中的 ‘r’才发现匹配不成功,于是从待查串计数器移到‘a’ 的上面,目标串重新回到开始,继续匹配。这里重复匹配就出现了,可以看到在目标串 ‘r’ 前面有pa 是和自己前面是一样的,也就是说,下次匹配可以从第三位p和目标串中的第三个位置开始比较,如下图


这样就达到了待测串中遍历器不用回溯,目标串的遍历器也减少回溯的目的,实现如下

int * Cal(char * str,int length)  //计算模式串{int* mod=new int[length];mod[0]=mod[1]=0;for(int i=2;i<length;i++)if(str[i-1]==str[mod[i-1]])mod[i]=mod[i-1]+1;else if(str[i-1]==str[0])mod[i]=1;else mod[i]=0;for(int i=0;i<length;i++)cout<<mod[i]<<" ";cout<<endl;return mod;}
int KMP(char *target,char *source,int tlength,int slength){int *mod=Cal(target,tlength);int tar=0,sour=0;  if(target==NULL||source==NULL||tlength<0||slength<0){cout<<"参数不合法"<<endl;return -1;}while(sour<slength){if(source[sour]==target[tar]){sour++;tar++;if(tar==tlength){cout<<"位置"<<sour-tlength<<"检测到目标串"<<endl;tar=0;}}else if(mod[tar]==0)  //如果该位置之前的串的后缀和其前缀不同{sour++;tar=0;}else tar=mod[tar];   //如果该位置之前的串的后缀和其前缀相同,利用该信息}cout<<"检测完毕"<<endl;return 1;}



原创粉丝点击