首页 > 代码库 > 模式匹配的KMP 算法
模式匹配的KMP 算法
常见的字符串匹配时,模式串长度为n,源串长度为m,则从头匹配,两个指针i指向源串,j指向模式串,如遇到不同则回溯使j=0,这样就要重复匹配会使效率变低。
由于在现在i之前 的模式串与匹配串的匹配是相同的,即回溯时,不用将模式串与源串进行匹配,而只将模式串与自身匹配即可得到其是否需要回溯以及回溯到何处。则我们可以在进行模式匹配之前,想对模式串进行自我匹配,来计算出对于i在模式串的任意位置匹配失败后回溯的位置。
而对于自身匹配的算法还有一个优化的地方在于,模式串在b位置匹配到自身的a位置,然后判断一下这两个位置的字符是否相同,如果相同,则将a位置的回溯位置赋值给b,如果不同,则说明没有必要回溯到这个位置,因为回溯后不匹配,则直接将其置为0,表示从0开始重新匹配、
失败函数的返回值为-1是用来设置其结构,使其能够在自我匹配时简单实现其功能,标识匹配失败重新开始,但其在模式匹配中效果与0相同,都是i置为0,j++,然后继续匹配。
自我匹配放在一个失败函数中,对模式字符串进行操作,然后将结果放在一个数组中方便查询。
试着写出c++代码:
这里每次遍历时,是判断第i个字符串如果相同,那么第i加一个字符串不符就要返回的位置,每次都是对i+1进行操作,所以最后一次会对数组中下标为n的字符进行操作,会越界,则之前建fail数组时,要考虑一下。
void FailString(int f[],const char* str){ int length = strlen(str); int i =0, k = -1; f[0] = -1; while( i < length){ if(k == -1 || str[i] == str[k]){ i++;k++; if(str[i] == str[k]) f[i] = f[k]; else f[i] = k; }else k = f[k]; } } bool compareString(const char* charA,const char* charB){ if( charA == 0 || charB == 0) return false; int Alen = strlen(charA); int Blen = strlen(charB); if( ! Alen || ! Blen ) return false; if( Blen > Alen)return false; int* fail = new int[ Blen+1 ]; FailString(fail,charB); int i = 0 , j = 0; while(i < Alen && j < Blen){ if( charA[i] != charB[j] ){ if(fail[i] == -1 ) j = 0; else j = fail[i]; }else j ++; i++; } delete[] fail; fail =NULL ; return j==Blen; } void main(){ char* s1 = "abcabcaabcabbac"; char* s2 = "abcabcabbac"; if(compareString(s1,s2)) cout<<"s1==s2"<<endl; cin.get(); }
模式匹配的KMP 算法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。