KMP算法

一种十分优秀的字符串匹配算法,时间复杂度为线性

首先定义如下变量:

a - 文本串

b - 模式串

我们又定义如下变量:

i - 指向文本串a的指针

j - 指向模式串b的指针

nxt - nxt[j]表示串b[0: j]中既是前缀也是后缀(不包括b[0: j]自身)的字符串的最大长度

 在a[i] != b[j]时,当前位置发生匹配失败,此时我们应该想到回退j,使得b[0: j]这样的最长前缀能够匹配到a[i - j: i],然后继续之后的匹配,假设此时nxt[j - 1] = x,则有b[0:x] == b[j - 1 - x: j - 1] == a[i - 1 - x: i - 1],所以j回退到nxt[j - 1]就是最好的选择

nxt数组求法:可以用串b[0: ]对串b[1: ]进行匹配求出,令nxt[0] = 0,此为 j 能回退到的最小位置。在自我匹配过程中,若是匹配失败,则 j 需要回退,可直接令 j = nxt[j - 1],因为 nxt[j - 1] 在遍历到 j 之前就已经求过,若是匹配成功,则令j++,nxt[j] = j即可

题目链接: 子串查找

#include <bits/stdc++.h>
using namespace std;
int nxt[1000005], res = 0;
void get_next(string b) {
    nxt[0] = 0;
    for (int i = 1, j = 0; i < b.size(); i++) {
        while (j && b[i] != b[j]) {
            j = nxt[j - 1];
        }
        if (b[i] == b[j]) {
            j++;
        }
        nxt[i] = j;
    }
}
void kmp(string a, string b) {
    for (int i = 0, j = 0; i < a.size(); i++) {
        while (j && a[i] != b[j]) {
            j = nxt[j - 1];
        }
        if (a[i] == b[j]) {
            j++;
        }
        if (j == b.size()) {
            res++;
            j = nxt[j - 1];
        }
    }
}
int main() {
    string a, b;
    cin >> a >> b;
    get_next(b);
    kmp(a, b);
    cout << res << endl;
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值