KMP算法

这位大大的博客关于KMP的原理的讲解KMP算法的大致讲解
这位大大的一篇很长很长的关于KMP的细致讲解KMP细致讲解


建议看第一篇自己理解后,再去第二篇验证自己的想法,而且这两篇博客里面的东西稍有不同,建议自己先Code一遍,再看第二篇,我的注释也会帮助你理解KMP中的一些边界处理的事

看了好久的KMP几天终于可以真正的理解了,那个next数组中的一个递归的概念真的很厉害next[next[j]] 看了上面的那篇博主的解析,才恍然大悟,以下是本人对其算法的一些注释,一些细致方面的解释。


#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 100
int next[MAX+1];

// next数组是从0开始的
// next[i] 表示的是 p[0..i] 这个串的 前缀和后缀的相同长度 
// 注意:
// 后缀和前缀不能够重合,不然就没有办法跳转了,
// 就会造成每次前缀和后缀的最长的长度都是i+1,
// 所以有了next[1] = 0,而不是 next[1] = 1;
void getnext(char *p)
{
    int j = 0;
    next[0] = next[1] = 0;
    // 遍历,得到next
    for(int i=1; i<strlen(p); ++i) {
        while( j>0 && p[i] != p[j] ) j = next[j];
        if( p[i]==p[j] ) j++;
        next[i+1] = j;
    }
}

void search(char *s, char *p)
{
    // j 表示 模式串当前比较的字符
    int j=0;
    // i 表示 当前比较的文本的字符
    for(int i=0; i<strlen(s); i++) {
        /*
         * 当文本中的字符串不相等时,模式串根据next跳到要比较的字符串的位置
         * 位置当然是相同相同的前缀和后缀的后一个
         * next记录的是前缀和后缀相同的长度,而不是下标, 顾 j=next[j]即可
         */
        while(j>0 && s[i]!=p[j]) j = next[j];
        // 文本的字符等于模式串的字符则下标+1
        if( s[i] == p[j] ) j++;
        /*
         * j 本来是字符比较的下标,因为在比较成功的前
         * 一定会执行前面的的 if( s[i] == s[j] ) j++的,所以匹配成功的标志为
         * j == strlen(p);
         */ 
        if(j==strlen(p)) {
            // i-j+1 是匹配成功的第一个字符串的位置
            printf("%d\n", i-j+1);
            // break;
            j = next[j];
        }
    }
}

int main()
{
    char *s = "babcbabcabcaabcabcabcacabc";
    char *p = "abcabcacab";
    getnext(p);
    for(int i=0; i<strlen(p); i++) 
        printf("%d,", next[i]);
    printf("\n");
    search(s,p);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值