kmp算法

原文来自某位大佬,链接后补
#include <iostream>
#include <vector>

using namespace std;
//KMP算法: 每次失配,S串的索引i不动,P串的索引j定位到某个数。T(n)=O(n+m),时间效率明显提高
vector<int> getNext(string p) {  //获取跳跃位,移动长度取决于公共元素长度

    int n = p.size(), k = -1, j = 0; //k 的值-1~~6 ,不会超过p.size()

    vector<int> next(n, -1);    //存放于容器vector中,0位存了-1,-1表示不存在相同的最大前缀和最大后缀
    while (j < n - 1) {
        if (k == -1 || p[j] == p[k]) {  //如果下一个不同,那么k就变成next[k],注意next[k]是小于k的,无论k取任何值。

            ++k; ++j;     //此处 k 的值是从0开始的,匹配成功,继续匹配下一个字符

            //较之前next数组求法,改动在下面4行
            if (p[j] != p[k])
                next[j] = k;   //之前只有这一行   此处k 的值就是前后缀公共元素的长度
            else
                next[j] = next[k]; //p[j] == p[k]
        } else {
            k = next[k];  //往前回溯
        }
    }
    return next; //匹配完成,获得所有 跳跃位/匹配值    /next里存的是前后缀公共元素的长度
}

int kmp(string s, string p) {  //s 为主串,p 为模式串
    int m = s.size(), n = p.size(), i = 0, j = 0; //从首位开始匹配

    vector<int> next = getNext(p);    //定义容器next ,传参并获取getNext :-1,0,0,0,-1,0,2

    while (i < m && j < n) {      //主串和模式串都在长度范围内匹配

        if (j == - 1 || s[i] == p[j]) {   //模式串下标为-1||匹配成功时
            ++i; ++j;                     //匹配下一位
        } else {          //否则
            j = next[j];  //
        }
    }
    return (j == n) ? i - j : -1;   //匹配结束,返回匹配结果;成功返回下标i-j,失败-1
}

int main() {
    cout << kmp("BBC_ABCDAB_ABCDABCDABDE", "ABCDABD") << endl; // kmp传入主串,模式串,然后输出结果
                                                                //Output: 15
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值