【无标题】


前言

简要记录下自己在考研期间学习了kmp算法后一些自己的理解。该算法是一种能够在O(m+n)的时间复杂度内完成字符串匹配的算法。其主要的核心依赖于next数组的构建和使用。但是不管是学习的考研视频,还是其他文章之类的很多人对于next数组的问题含糊其辞或者一笔带过,导致我花费了大量的时间在这上面。因此写篇文章简要记录下自己遇到的问题和一些理解。

一、KMP算法是什么

KMP 算法(Knuth-Morris-Pratt 算法)就是一个由三个人提出来的一种高效的字符串匹配的算法。

二、代码详解

1.

代码如下(示例):

 注意:当前代码下标是从1开始的,为了方便。如果下标是从0开始,或者是左移的,要进行相应的改变。

next数组的定义:在子串的第j个字符与主串发生匹配失败时,则跳到子串的next[j]位置继续匹配。(我个人感觉也可以理解成,从1到j-1这个子串的最长公共前后缀长度+1

关于什么是最长公共前后缀,这里就不多解释了,很好理解。

为什么是最长公共前后缀长度+1,因为我们是从下标1开始的,这就相当于把原本的整个数组右移了。如果不+1,那发生匹配失败时,我们会找next【j-1】这个位置,而不是next【j】。这个看自己喜欢。

        int sl = s.size(),pl = p.size();//sl是主串,pl是模式串


        //匹配开始
        int i = 1,j = 1;
        while(i < sl && j < pl){
            if(j == 0 || s[i] == p[j]){
                i++;
                j++;
            }
            else{
                j = next[j];//回退到上一个最长相同前后缀长度的位置
            }
        }

2.如何求next数组

这也是整个算法的核心部分:

分三个部分讨论

1、当j == 0时,此时没有相同前后缀。直接i++,j++即可。即开始下一次的匹配。

2、当p[i] == p[j]时;

        next[i+1] = j+1

即next【++i】 = ++j;不理解为什么,再去看一遍上面next数组的定义。

(在这之前前面从1到j-1这个子串和i-1到i-j+1这个子串是完全相等的,要不然也不会轮到第i个字符和第j个字符开始匹配)

3、当p[i] != p[j]时;我当时最大的疑惑就是这里,为什么回退到

        j = next【j】;

画个图就好理解了

 

 

具体证明可以自行百度

代码如下(示例):

//先初始化next
        vector<int> next(pl+1,0);
        next[1] = 0;

        int i = 1,j = 0;
        while(i < pl){
            if(j == 0 || p[i] == p[j]){
                i++;
                j++;
                next[i] = j;
            }
            else j = next[j];
        }

总结

!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值