有关KMP算法的解释以及相关代码

 有关KMP算法的介绍
众所周知,KMP算法是用来处理字符串相关问题的算法,在KMP算法之前有我们熟悉的暴力算法(朴素算法)如下:

bool Cmp(string a,string b){  // a是总串 b是模式串(寻找的子串)
    int length2=b.length;
    for(int i=0;i<(a.length-b.length)+1;i++){
        if(a.substr(i,length2)==b)   //如果a的从i开始 length2长度之后和b串匹配
            return true;
    }
    return false;
}

因为这么跑的话时间复杂度是O(M*n) 因为每一个小循环都要比较n个数,大循环要执行m-n+1次数 所以总的是m*n 因此在这个基础上产生了KMP算法O(M+N)

KMP算法的核心思想就是在朴素算法的基础上修改了总的字符串前进的方式以及模式串的前进方式(因为朴素算法的前进方式是 模式串指针归为原位,总字符串前移一个位置。)但KMP的核心思想是,如果模式串的第j个字符不匹配,总字符串的指针I不变 模式串的指针j指向next[j]的位置之后比较a[i]和b[j];而计算next的方法如下:我们以aaaab为例  

序号12345
对应字母aaaab
next[i]01234


等我们计算完对应的next之后就可以构架后续代码了

//这里假设next[]设置为全局变量
//指导书上用的起始位置都是1 方便对应next
bool kmp(string a,string b){ //a是总串 b是模式串
    int j=1;
    for(int i=1;i<=(a.length-b.length)+1;){
        if(a[i]==b[j]){
            i++;
            j++;
        }
        else{
            j=next[j];
            if(j==0){//教科书把本次条件判断放到第一个if中 用'|'连接
                j++;
                i++;
            }
        }
        if(j>=b.length)
            return true;
        else
            return false;
    }
}

后序还学习了kmp的改进代码 进行的改动t就是增加了一个nextval 数组,因为在一些时候会存在特殊情况,例如上述提到的aaaab样例, 如果第三个不匹配 那个我们可以确定总字符串中第三个肯定不是a 但由于我们设计的next数组,我们会让j跳到next[j]也就是next[3]处,此时next[3]等于2 然后 i仍然不变,可以确定地是a[i]一定不等于a 但是当j=next[3]=2的时候  b[j]是等于a的因此两个一定不相等,又要多进行一次判断。会使时间增加。因此提出了一个nextval的数组,用来优化next数组

计算方式如下:如果序号为i的next[i]所指的序号的字母和i的字母一样 则nextval[i]=nextval[next[i]] 否则就不变.

序号12345
字母aaaab
next[i]01234
nextval[i]00004

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值