KMP算法

 参考https://www.bilibili.com/video/BV19Q4y1c7ko?t=3967.9

看了好多文章和视频,解法各种各样,我真的是看晕了,大多数将 nxt 数组的构建都讲太含糊,很难理解KMP算法的核心。这里推荐看看左神的讲解,相当细致,看完后茅塞顿开。

 

例题E - Shift String

这里以atcoder430的E题为例,我看了挺多题解,好多都是用字符串哈希写的,这里提供一个KMP算法的思路。

查看代码
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6 + 5;

int nxt[N];

void getNxt(const string& s){
    nxt[0] = -1;
    nxt[1] = 0;
    int j = 2, cn = 0;
    while(j <= s.length()){
        if(s[j - 1] == s[cn]){
            nxt[j++] = ++cn;
        }else if(cn > 0){
            cn = nxt[cn];
        }else{
            nxt[j++] = 0;
        }
    }
    return ;
}

void solve(){
    string a, b;
    cin >> a >> b;
    a = a + a;
    int len1 = a.length(), len2 = b.length();
    getNxt(b);
    //KMP算法
    int i = 0, j = 0;
    while(i < len1){
        if(a[i] == b[j]){
            i++, j++;
        }else if(j > 0){
            j = nxt[j];
        }else{
            i++;
        }

        if(j == len2){
            cout << i - j << endl;
            return ;
        }
    }
    cout << -1 << endl;
    return ;
}

字符串A每次把第一个字符移动到末尾,对于字符串B来说就是不断向右移动找到与之匹配的字符串A的位置,这不就是KMP算法的过程吗,我们先构建nxe数组,记录字符串B每个字符的最长公共前后缀,执行KMP算法,移动 i 与 j,直至匹配成功后退出。

posted @ 2025-11-13 00:43  菜鸡の编程日常  阅读(9)  评论(0)    收藏  举报