Welcome

首页 / 软件开发 / 数据结构与算法 / KMP模式匹配算法概述

KMP模式匹配算法概述2015-09-20我们经常会遇到一种情况是匹配两个字符串,看strPar中是否含有str子串,如果有则返回子串在父串strPar中的位置,如果不存在则返回false.

很明显,我们可以通过暴力求解的方式解决该问题。即从strPar第一个字符和子串进行比较,若成功则返回第一个0,若不成功,再第二个字符开始比较,这样的时间复杂度为O(M*N).可以看出,这个复杂度是相当高的,那么我们有没有一种复杂度会降低呢?显然,有一种叫做KMP算法可以大大降低复杂度O(M+N)。该算法通过记忆的方式,避免了很多无用功。

比如字符...p1,p2,p3.....p‘,p"",p"""...

假设p1,p2和p",p""是一样的,当我们进行比较的时候若在p"""比较失败,只需推到p3与父串进行比较即可,因为他前面的肯定是相同的。同时父串并不需要倒退。

那么到底怎么退,退多少呢?

这就需要有一个记忆数组,比如abaabcac

void getNext(const char* str,int next[]){int i=0,j=-1;next[i]=j;assert(str);while(i<(int)strlen(str)){if(j==-1||str[i]==str[j]){i++,j++;next[i]=j;}elsej=next[j];}}
得到了next数组之后,通过strPar和str比较。若相同则i++,j++;否则str往后退,即j=next[j];

int Index(const char* strPar,const char* str,int next[]){int i=-1,j=-1;assert(strPar&&str);int m=strlen(strPar),n=strlen(str);while(i<m&&j<n){if(j==-1||strPar[i]==str[j])i++,j++;elsej=next[j];}if(j==strlen(str))return i-j;elsereturn -1;}