kmp算法可以有效提高字符串匹配的速度,当匹配字符串中出现较多循环节时尤其有效,但是当一个字符串中几乎每一个字符都不相同的时候,kmp算法并不能很好的加速整个匹配过程,但是光思想就可以甩brute-force算法几条街。下面给出了两种算法的具体实现,对于kmp算法,其关键思想是:当与源字符串出现不匹配时,无需从头再来,而是可以只退回到next[j]的位置,j为当前匹配字符串的位置,所以kmp算法的关键在与如何求解next数据,下面是计算next数组的公式,根据公式实现方法很多,但是万变不离其宗:
{ 0-1 when j=0
next[j]= { max{k|0<k<j|"t0...tk-1"=="tj-k.....tk-1"}
{ 0 else
下面是两种算法的实现代码,main函数仅供测试:
(1)、brute-force算法
#include <string> #include <stdio.h> #include <stdlib.h> #include <string.h> /* *Author:hujian *Time:2016/5/22 *description:the pre-KMP algorithm *it can solve some sample problem,but not so easy to *handle the big-data. * */ using namespace std; int brute_force(string src,string dst) { int i=0,j,k; while(i<src.length()){ for(j=i,k=0;j<src.length()&&k<dst.length()&&src[j]==dst[k];j++,k++); if(k==dst.length()){ //i find the position return i; } i++; } return -1;//return -1 means i can not find the sub-str in src string } int main(int argc,char**argv) { if(argc!=3){ printf("usage:%s [src-string] [dst-string]\n",argv[0]); return !0; } else if(brute_force(argv[1],argv[2])!=-1){ printf("[%s] include [%s]\n",argv[1],argv[2]); } else{ printf("[%s] do not include [%s]\n",argv[1],argv[2]); } return 0; }
(2)、kmp算法
#ifndef _KMP_TEMPLATE_H_ #define _KMP_TEMPLATE_H_ #include<iostream> #include<string> #include<stdio.h> #include<stdlib.h> #include<string.h> using namespace std; int Next[100001]; string s,p; //get next array void getnext(int len) { int j,k; j=0,k=-1,Next[0]=-1; while(j<len){ if(k==-1||p[j]==p[k]){ j++,k++; Next[j]=k; }else{ k=Next[k]; } } } // //kmp //@ls:ls is length of source string //@lp:lp is length of pattern string // int kmp(int ls,int lp) { int i = 0, j = 0; getnext(lp); while (i < ls&&j < lp){ if (j == -1 || s[i] == p[j]){ i++, j++; }else{ j = Next[j]; } if (j == lp){//kmp ok. return (i-lp); } } return -1;//-1 means i can not pattern the str in src string } int main(int argc,char**argv) { if(argc!=3){ printf("usage:%s [src] [pattern]\n",argv[0]); return -1; } s=argv[1],p=argv[2]; cout<<"s="<<s<<" p="<<p<<endl; int res=kmp(s.length(),p.length()); if(res!=-1){ printf("[%s] contain [%s] at>>>>>>>>>>>>>>>[%d]\n",argv[1],argv[2],res); } else{ printf("[%s] not contain [%s]\n",argv[1],argv[2]); } return 0; } #endif //end of kmp template header ///<2016/5/23> hujian nankai university ///<theme:kmp>