KMP模板

KMP 模板

#include<iostream>
#include<cstring>
#define maxn 100

using namespace std;

int next[maxn];

// next[j]存储的是当第j个字符匹配失败时,就将k模式串指针跳到next[j]处。故只有在匹配失败时才会用到next[] 中存储的值
void get_next(char *p){
    int k=-1,j=0;  //next[]数组的第一个值一定是-1,用-1“标记”第一个字符就匹配失败的情况。 j从0位开始遍历模式串,直到pl-1
    int pl=strlen(p);

    next[0]=-1; //next[]中存储的永远是-1
    while(j<pl){ //j要从0遍历模式串直到pl。 因为在上面next[0]的值已经给出,故 j在while循环中实际从1开始遍历模式串,直到pl。
        if(k==-1 || p[k] == p[j]){ //如果k==-1; 说明当前不匹配的是第二个(大括号里j++之后j就到达2了)字符,它前面只有第一个字符,故其前面的最大公共长度是0。
                                   //所以此时next[1]=k++;(next[1]是第二个字符,k++ 之后等于0。)
            k++; j++;
            next[j]=k;
        }
        else
            k=next[k];//求第二大长度
                      //若p[k] != p[j],则可以把其看做模式匹配的问题,即匹配失败的时候,k值如何移动,显然k=next[k]。 //个人小想法:若把p[k] == p[j]时得到
                      //的公共长度称为最大公共长度,便可以把k退一步得到的公共长度称为公共第二长长度了。哈哈。。。
    }
}

int KMP_search(char *s,char *p){ //返回值是与模式串相同的子串在主串中的首字符的的下标。
    int i=0,j=0; //i,j分别遍历主串s,模式串p。
    int slen=strlen(s);
    int plen=strlen(p);

    while(i<slen && j<plen){ //使匹配结束的原因两个:(一) i<slen, (j>=plen),即主串被遍历完了,但即便这样也没有找到与模式串相同的子串。
                                                   //(二) j<plen, (s<slen),即主串还没有被遍历完,就找到了与模式串相同的子串。
                                                   //(三) i,j同时达到i>=slen,j>=plen,说明恰好在遍历到主串的最后一个最后一个字符时,找到与模式串相同的子串。
        if(j == -1 || p[j] == p[i]){//j==-1说明是在第一个字符就不匹配的情况下产生的j=next[0],之后j==-1 ,既然第一个字符就不匹配,那么下一步就只能i、j均加1了。
                                    //或说:j == -1表示又已经开始从头遍历模式串p,且第一个字符就匹配失败(next[0] == -1),接下来就只能有一种操作咯:i++; j++;
            i++; j++;
        }
        else
            j=next[j]; //当前字符不匹配时采取措施:j=next[j]。
    }

    if(j>=plen) return i-plen; //如果p>=plen,说明模式串被成功遍历完了一遍,即说明在主串中找到了与模式串相同的子串。
//    else //如果至while循环结束,j都还是j<plen,说明在主串中最终都没有找到与模式串相同的子串。
    return -1; //没有找到与模式串相同的子串,就返回-1。
}

int main(){
    char s[maxn] = "abcdefgabcg"; //主串
    char p[maxn] = "abcg"; //模式串
    int position = KMP_search(s,p); //返回值是主串中与模式串相同的子串的首字符的下标值。
    if(position == -1) cout<<"未找到"<<endl;
    else cout<<"The positon of '"<<p<<"' in the '"<<s<<"' is "<<position<<endl;

}

KMP模板 代码解释

** KMP算法的思想网络上已有众多大神的讲解,小编便不再献丑了。因初学时应用之际对代码实现具有颇多疑惑,想必有许多朋友也是如此。现对KMP模板的代码进行了“逐条”解释,希望对您有所帮助。不当之处,敬请斧正。以下众大神之讲解对本人帮助颇多,现列举如下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张之海

若有帮助,客官打赏一分吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值