【C++】Day19 KMP算法 AcWing 831. KMP字符串 (算法基础课笔记)


前言
你好啊,我最近在学acwing的算法基础课,备战蓝桥杯,如果你也是一样的话,欢迎一起学习~


在这里插入图片描述

一、题目&解读

1、题目

题目链接{点击跳转}

在这里插入图片描述

二、思路

1、KMP是什么?

图片来源点击跳转
在这里插入图片描述
图中的移动位数 也就是构造next[i]的过程了

2、思路

先想暴力怎么做,然后再进行优化

3、构造next[i]

看过上图的前缀和后缀,next[i]的构造是找到前缀等于后缀的那个位置
在这里插入图片描述
构造next[i]=value的例子
其中value表示前缀和后缀相同的字母的数量
另外i 表示指针指到哪个元素下
在这里插入图片描述
代码实现

// 构造next数组
    for (int i = 2, j = 0; i <= n;i ++) {
    
    
        while (j && p[i] != p[j+1])
            j = ne[j];// 对模式串进行匹配,如果没有匹配成功,j变成ne[j]的位置
        if (p[i] == p[j+1])
            j++;// 匹配成功,j到后一位
        ne[i] = j;// 记录匹配成功的i位和j位的对应关系
    }

4、匹配的过程

移动指针 找不同元素 图中比较s[7]p[6+1]
在这里插入图片描述

在这里插入图片描述
此时模板串的前缀 和 后缀 都和上面的相同 匹配完成

//    利用ne数组进行模式匹配
    for (int i = 1, j = 0; i <= m;i ++) {
    
    
        while (j && s[i] != p[j+1])
            j = ne[j];// 没匹配成功, j变成ne[j]的位置
        if (s[i] == p[j+1])
            j ++;// 匹配成功,j往后一位
        if (j == n) {
    
    // 如果完全匹配完毕
            printf("%d ", i - n);
            j = ne[j];// 寻找p在s中的下一次出现的位置,利用ne数组优化时间复杂度
        }

如果还是不懂 建议多刷几遍y总的讲解 y总,yyds!!

扫描二维码关注公众号,回复: 13712154 查看本文章

三、AC代码

时间复杂度 O(n+m)

#include <iostream>
using namespace std;
const int N = 1e5+10,M=1e6+10;
int n, m;
int ne[N];//ne表示next 建议不要起next 容易报错
char s[M], p[N];

int main () {
    
    
    cin >> n >> p + 1 >> m >> s + 1;

   // 对模板串构造 next 数组
    for (int i = 2, j = 0; i <= n;i ++) {
    
    
        while (j && p[i] != p[j+1])
            j = ne[j];// 对模式串进行匹配,如果没有匹配成功,j变成ne[j]的位置
        if (p[i] == p[j+1])
            j++;// 匹配成功,j到后一位
        ne[i] = j;// 记录匹配成功的i位和j位的对应关系
    }

    
    //    利用next数组对模式链匹配
    for (int i = 1, j = 0; i <= m;i ++) {
    
    
        while (j && s[i] != p[j+1])
            j = ne[j];// 没匹配成功, j变成ne[j]的位置
        if (s[i] == p[j+1])
            j ++;// 匹配成功,j往后一位 
        if (j == n) {
    
    // 如果完全匹配完毕
            printf("%d ", i - n);
            j = ne[j];// 寻找p在s中的下一次出现的位置,利用ne数组优化时间复杂度
        }
        
    }
        return 0;
}

四、总结

学数据结构 最主要的还是要画图,先画一遍,代码自然就能够写了。

结尾:

感谢你能看完,希望对你有帮助 ,如有错误欢迎指正,码字不易,给个赞呗 在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_49486457/article/details/122973038