ACM-KMP初步

优质的博客、视频讲解

视频:https://www.bilibili.com/video/av3246487?from=search&seid=16000927909169712834
讲述很详细,包括对next数组的理解(到现在还有点迷糊)、next的作用、next中i、j的跳跃取值等等讲的十分详细。
博客:https://blog.csdn.net/luoshengkim/article/details/44724981
写的非常详细,但是不如视频中的实例讲的更容易理解。
(注意上边视频和博客构造next数组的方式有些不同:视频中的next)

大致过程理解

得到一个next数组

1、含义:是在这个元素前面所形成的区间的这个 子串(或叫子数组区间)的最长的并且相同的前缀后缀的长度,赋到这个next数组。
理解前缀后缀:abcbcb =>前缀a ab abc…… 后缀=>b cb bcb……

2、例子:(就拿b站视频中的例子做例子(例子都举得非常好,很帮助理解,但由于自己鰔鶸还是理解的不好。)=>但是得到next数组的思路是我看博客的理解。)
模板串(也就是短的那个字符串(数组)):1 1 2 1 1 2 1 1 1
首先令next[0]=-1;
然后遍历模板串(数组),next[1] = 0 (因为再1前面形成的区间相同的前缀后缀==1)。next[2] = 1 (因为2前面的区间1 1 有一个共同的前缀后缀,故等于1。)
next[3] = 0; next[4] = 1; next[5] = 2; next[6] = 3; next[7] = 4; next[8] = 5;

3、模板:

void getnext(){
    int j=0,k=-1;
    next[0]=-1;
    while(j<m){
        if(k==-1||p[j]==p[k]){    //p为模板串
            j++;
            k++;
            next[j]=k;
        }
        else
            k=next[k];
    }
}

4、时间复杂度:O(n)……n为模板串的长度。

运用kmp搜索对原串和模板串(原数组和模板数组)进行搜索匹配

1、过程:遍历两个串会分别有一个位置值:
如果原串[原串的位置值]==模板串[模板串的位置值] =>位置都往后移。
如果原串[原串的位置值]!=模板串[模板串的位置值]=>
①如果暴力搜(bf):让原串的位置退回到与相对于模板串的开头的位置。
②如果kmp:让原串的位置退回到与相对月模板串开头的前缀相同的后缀的位置。(减少遍历次数。)

2、时间复杂度:O(m)……m为原串的长度。

3、模板:匹配输出位置,不匹配输出-1

int kmp(){
    int i=0,j=0;
    getnext();
    while(i<n){
        if(j==-1||s[i]==p[j]){       //s为原串   p为模板串
            i++;
            j++;
        }
        else
            j=next[j];
        if(j==m)    //m为模板串的长度
            return i;
    }
    return -1;
}

kmp字符串匹配算法的优点:用空间换时间

kmp字符串匹配算法通过多开了一个next数组来记录前缀后缀相同情况来减少了循环次数,从而达到节省时间的优点。
(bf的时间复杂度:O(m*n) , kmp的时间复杂度:O(m+n)。)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值