KMP再思考

看过很多篇关于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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值