串的模式匹配算法之KMP算法代码

串的模式匹配算法之KMP算法代码

KMP算法是一种字符串的模式匹配算法,使用BF(Brute Force,暴力)算法的时间复杂度为O((m - n + 1)*n),使用KMP算法的时间复杂度为O(m + n)。
其中m为主串的长度,n为模式串的长度。

BF算法代码

char * strFind(const char *string,const char *substring){
     
 assert(string != NULL && substring != NULL);
 int m = strlen(string);
 int n = strlen(substring);
 if (m < n){
     
  return NULL;
 }
 for (int i = 0;i <= m - n;i++){
     
  for (int j = 0;j < n;j++){
     
   if (string[i + j] != substring[j])
       break;
  }
  if (j == n){
     
   return string + i;
  }
 }
 return NULL;
}

KMP算法的比较过程

主串:char src[] = “ababcabcacbab”;
模式串:char patn[] = “abcac”;
第一趟匹配:

第二趟匹配:

第三趟匹配:

第三趟匹配的时候模式串的第一位没有参与比较,因为KMP算法已经推得此位必然相等。

KMP算法代码

#include
#include 
using namespace std;

void get_nextval(char const* ptrn,int plen,int* nextval){
     
 int i = 0;
 nextval[i] = -1;
 int j = -1;
 while(i < plen - 1){
     
  if (j == -1 || ptrn[i] == ptrn[j]){
     
   ++i;
   ++j;
   if (ptrn[i] != ptrn[j])
       nextval[i] = j;
   else
       nextval[i] = nextval[j];
  }
  else{
     
   j = nextval[j];
  }
 }
} 

int kmp_search(const char* src,int slen,const char* patn,int plen,const int* nextval,int pos){
     //从pos位开始匹配 
 int i = pos,j = 0;
 while(i < slen && j < plen){
     
  if (j == -1 || src[i] == patn[j]){
     
   ++i;
   ++j;
  }
  else{
     
   j = nextval[j];//当匹配失败时直接用patn[j_next]与s[i]比较 
  }
 }
 if (j >= plen)
     return i - plen;
 else
     return -1;
}

int main(){
     
 char src[] = "ababcabcacbab";
 char patn[] = "abcac";
 int nextval[5];
 int slen = strlen(src);
 int plen = strlen(patn);
 get_nextval(patn,plen,nextval);
 cout<<"nextval数组为:"; 
 for (int i = 0;i < plen;i++){
     
  cout<<nextval[i]<<" ";
 }
 cout<<endl;
 cout<<"字符串在下标为"<<kmp_search(src,slen,patn,plen,nextval,0)<<"处(下标从0开始)匹配成功"<<endl; 
 return 0;
}

KMP算法运行结果

串的模式匹配算法之KMP算法代码_第1张图片
以上内容都来源于《王道程序员求职宝典》。

你可能感兴趣的:(王道程序员求职宝典)