KMP再思考

来源:互联网 发布:手机上传淘宝主图视频 编辑:程序博客网 时间:2024/06/06 04:04

看过很多篇关于KMP的博文,老感觉总结的结论相互之间有出处,这里我把最终整理出来的结论分享一下。【其实私心想想有出处的地方也没有对错之分,只是看匹配发生在next生成的时候,还是匹配长字符串的时候】

第一部分:getNext

思想:

      next[0] = -1;

      p[0…k-1] =p[j-k…j-1]的最大的k(k<j), next[j] = k  eg:abdabc next[5] = 2; 但是如果匹配不到(k=0)next[j] = 0,如果匹配到了但是结束字符也一样的话next[j] 仍要为0 eg:abcabc next[5] = 0,这些情况下如果又与首字符一样的话next[j]==-1;


完整代码:

#include<iostream>#include<cstdio>#include<string>#include<cstring>const int Max = 10;using namespace std;int next[Max];bool equals(string s1, string s2){    bool flag = true;    for(int i = 0 ; i < s1.length() ; i++){        if( s1[i] != s2[i] ) flag = false;    }    return flag;}void getNext(string str2){    memset(next,0,sizeof(next));    int pos = 0;    next[pos] = -1;    pos++;    for( ; pos < str2.length() ; pos++){        int k = pos-1;        for( ; k > 0 ; k--){            if( equals( str2.substr(0,k),str2.substr(pos-k,k) ) )next[pos] = k;        }        //本身没有相匹配的字符,或者匹配到最后发现相同段同样应该将它归零        if(k==0 || str2[pos] == str2[k]) {            next[pos] = 0;            if(str2[pos] == str2[0]) next[pos] = -1;        }    }}int main(){    string str1;    string str2;    cin>>str1;    cin>>str2;    getNext(str2);    int match = 0;    for(int i = 0 ; i < str1.length() ; i++){        if( str1[i] == str2[match] ) match++;        else{            //cout<<"current fail_position::"<<i<<endl;            //next[pos] = -1;对str1的下一个字符继续匹配,但是str2从头            //next[pos] != -1;对str2的当前字符再次匹配,str2从避免重复的指定开始位置开始            if( next[match]==-1 ){                match = 0;            }else{                match = next[match];                i--;            }        }        if( match == str2.length() ) {            cout<<"end match"<<endl;            return 0;        }    }    return 0;}


0 0
原创粉丝点击