KMP详细解释及KMP算法模板

KMP算法模板 KMP模板 ======================================================================== 立即下载
KMP是什么,KMP解决什么类型的问题

KMP全称为Knuth Morris Pratt算法,是一种高效的字符串匹配算法,寻找一个字符串中是否包含另一个字符串,例如

char *s = "ababababcab";
char *p = "ababc";

s为模板串(主串),p为子串,在s中找到p的位置

暴力匹配算法 O(n*m)

暴力匹配算法不做过多解释,举个例子即可
匹配到第4个字符时匹配失败则i+1继续向后匹配

ababababcab
ababc

则i+1继续向后匹配

ababababcab
    ababc

匹配失败继续向后匹配直到如图

ababababcab
        ababc

匹配成功
此时我们可以发现当我们已经匹配了一部分字符串但下一个字符不相等时,我们还有一些信息可以利用,比如

ababababcab
    ababc

这时已经匹配了4个字符相等,我们可以根据这个信息来简化算法时间复杂度,这时我们引入KMP算法

KMP算法O(n+m)

我们可以利用已经匹配的字符来简化枚举过程,当已经匹配成功了4个字符时,我们是不是可以让字串向后移动来使得子串和模板串继续匹配?
例如

ababababcab
    ababc

此时我们让子串向后移动而模板串不动,使得模板串可以继续向后继续匹配

ababababcab
        ababc

此时匹配成功则继续向后匹配
而这样的移动就是KMP的next数组的用处
next数组的含义是一个固定字符串的最长前缀和最长后缀相同的长度,并且长度小于(不能等于)固定字符串本身,使得当匹配失败我们让子串向后移动最少的距离使模板串可以继续匹配,也就是说在某个字符失配时,该字符对应的next 值会告诉你下一步匹配中,子串应该跳到哪个位置
例如
在这里插入图片描述

假设我们在模板串的i位置和字串的j+1的位置匹配失败,此时我们将字串向后移动
j是我们匹配成功的最后一个字符
在这里插入图片描述
我们令j = next[j], 回忆一下next的数组含义next数组的含义是一个固定字符串的最长前缀和最长后缀相同的长度,此时

在这里插入图片描述
字符串移动到P2的状态,而这时P1,P2的绿色部分相等才能和模式串继续匹配,我们还可以发现

在这里插入图片描述
此时P1,P2的这两个绿色部分也是相等的,所以P中的绿色部分是相同的
在这里插入图片描述

所以也说明了next数组含义是一个固定字符串的最长前缀和最长后缀相同的长度,让前后缀相同我们才能使模板串继续匹配,而最长则保证了我们能找到所有的与模板串匹配的子串同时也能使子串与模板串尽快匹配,我们先不管next数组是怎么求得的我们先利用next数组实现KMP算法

KMP算法流程
// s[]是模板串,p[]是子串,n是s的长度,m是p的长度
// 匹配
for (int i = 1, j = 0; i <= n; i ++ )//由于我们令i与j+1匹配,所以i初始化为1, j初始化为0, 同时s与p的第一个字符在1位置,不在0位置
{
    while (j && s[i] != p[j + 1]) j = ne[j];//当j不为0且子串不能和模板串继续匹配时,让j = next[j], 判断能否继续匹配
    if (s[i] == p[j + 1]) j ++ ;//如果能继续匹配,则继续
    if (j == m)
    {
        j = ne[j];
        // 匹配成功后的逻辑
    }
}
next数组实现

再强调一遍next数组含义next数组的含义是一个固定字符串的最长前缀和最长后缀相同的长度,由于next数组只与子串有关所以我们应该先对子串进行预处理,处理出next数组,处理next数组方式也与KMP实现过程类似。我们把P子串当作模板串和子串进行匹配,假设我们当前要求next[i]的值,匹配到如下情况
在这里插入图片描述
当p[i] == p[j+1]时,则j+1的值是不是就是next[i]的值,也就是长度为i的子串最长前缀和最长后缀相同的长度,如图
在这里插入图片描述
如果p[i] != p[j+1],同KMP过程,1~j这一段是匹配的,则令j = next[j],继续找下一个能匹配的位置,由于我们的j是从P串的开头位置开始,所以只要当p[i] == p[j+1]时,next[i] = j + 1.
上代码

//求模式串的Next数组:
for (int i = 2, j = 0; i <= m; i ++ )//next[1] = 0, 所以i从2开始
{
    while (j && p[i] != p[j + 1]) j = ne[j];//匹配失败,j = next[j], 继续匹配
    if (p[i] == p[j + 1]) j ++ ;//匹配成功,换个写法就是j = j + 1,就是让j到j+1的位置,并且赋值给i
    //如果p[i] != p[j + 1],则出while循环的条件是j = 0, 说明没有前缀和后缀相同的长度,next[i]值也为0
    ne[i] = j;
}

KMP完整模板
// s[]是模板串,p[]是子串,n是s的长度,m是p的长度
//求模式串的Next数组:
for (int i = 2, j = 0; i <= m; i ++ )
{
    while (j && p[i] != p[j + 1]) j = ne[j];
    if (p[i] == p[j + 1]) j ++ ;
    ne[i] = j;
}

// 匹配
for (int i = 1, j = 0; i <= n; i ++ )
{
    while (j && s[i] != p[j + 1]) j = ne[j];
    if (s[i] == p[j + 1]) j ++ ;
    if (j == m)
    {
        j = ne[j];
        // 匹配成功后的逻辑
    }
}

模板来自ACwing:ACwing模板

CMAC算法原理 2、K1 通过以下运算导出:若 L 的最高有效位等于 0,则 K1 是 L 的左移 1 位。3、K2 通过如下运算导出:若 K1 的最高有效位等于 0,则 K2 是 K1 的左移 1 位。采用了 AES 算法中的类似 CBC 模式的加密方式,即对前一个分组的密文与当前分组的明文进行异或操作后在加密,2、分块处理:首先将消息分成多个固定长度的块,若消息长度不是块大小的倍数,则可以使用填充来将其填充到合适的大小。1、子密钥计算,通过主密钥生成子密钥(key1,key2),子密钥用于最后一个块处理; 阅读详情

相关推荐

手把手拆解UCIe协议层:从Raw Mode到Flit Mode,数据包到底经历了什么?

本文深入解析UCIe协议层的数据包处理机制,从Raw Mode到Flit Mode的三大变体(Standard 256B、68B-Enhanced、Latency-Optimized),详细揭示数据包在不同模式下的封装与转换过程。通过工程师视角,展示协议层如何实现多模式动态切换、错误恢复及与D2D Adapter的协同设计,为芯片级互连技术提供实践指导。

weixin_28728495的博客 240

kmp算法模板

KMP算法是一种时间复杂度为O(m+n)的字符串匹配算法,其中m和n分别为模式串和文本串的长度。其主要思想是利用已匹配到的前缀信息,避免在匹配过程中重复地搜索已经比较过的字符。具体实现需要用到getNext函数来求出模式串的next数组,kmp_search函数用于搜索模式串在文本串中的位置,并返回匹配的位置下标。

m0_73635448的博客 771

三相SVPWM逆变器双闭环PI解耦控制:从dq坐标系到参数整定实战

本文深入解析了三相SVPWM逆变器的双闭环PI解耦控制技术。通过引入dq坐标系,将交流量转换为直流量,并结合前馈补偿实现电流环的解耦控制。文章详细阐述了从数学模型推导、控制器设计到参数整定与SVPWM实现的完整流程,为工程师提供了从理论到实战的系统性指导。

weixin_28292761的博客 405

KMP 算法详解

KMP算法是一种高效的字符串匹配算法,算法名称取自于三位共同发明人名字的首字母组合。该算法的主要使用场景就是在字符串(也叫主串)中的模式串(也叫子串)定位问题,常见的有“求子串出现的起始位置”、“求子串的出现次数”等。

这里是阿安的博客 5万+

集成电路模拟版图入门-版图基础学习笔记(一)

集成电路设计模拟版图入门笔记,了解版图的定义、意义、工具、设计流程。认识版图及版图组成的两大部件,版图编辑器有哪些,电路图编辑器,了解工艺厂商等。

weixin_52955333的博客 2万+

4D毫米波雷达点云可视化实战:从CANFD原始数据到Matplotlib三维动态图

本文详细介绍了4D毫米波雷达点云可视化实战,从CANFD原始数据解析到Matplotlib三维动态图实现的全流程。通过解析CANFD数据帧结构、点云数据编码原理,并结合Python实现CANFD通信接口,帮助开发者掌握4D雷达数据处理与优化技巧,最终实现高性能的3D点云动态可视化。

u9v0w的博客 568

【算法】KMP模板(C++)

C++实现基础KMP匹配算法模板

xhd0728的博客 3011

网格聚类 Grid Clustering/Grid-based Clustering

本文主要简单介绍了网格聚类的基本概念,优缺点,应用场景,建模时的注意事项,评价指标,实现方法,python示例和模型参数等。

JasonH2021的博客 4828

【算法】KMP算法模板

#include<bits/stdc++.h> using namespace std; void KMP(string a,int n,int Next[]){ //a是待求子串,n是待求子串的长度,Next数组 int len=0; int j=1; Next[0]=0; while(j<n){ if(a[j]==a[len]){ /*当两者相等时,说明j的位置和前面对应前缀的位置相等, .

Elephant_King的博客 620

由JavaScript版迷宫游戏引出Java版迷宫地图生成器

Java案例:迷宫地图生成器 一、引入问题 本期18软件1班网页脚本实训项目是完成一个JavaScript版迷宫游戏。 迷宫地图是如何生成的呢?很简单,将一个正方形区域等分为若干行与若干列,比如25行25列,这样就有625个单元格,用一个二维数组map[25][25]就可以保存625个单元格信息,map[i][j] = 1表示该单元格要绘制砖,而map[i][j] = 0表示该单元格不绘制砖。 ...

howard2005的专栏 1473

【YOLOv11多模态涨点改进】独家创新首发 | TGRS 2025 | 引入CDFIM跨模态差异特征交互模块,通过差异特征提取和融合增强机制,减少了冗余信息,显著提升了小目标的检测精度,高效涨点改进

🔥本文给大家介绍使用 CDFIM跨模态差异特征交互模块改进 YOLOv11多模态目标检测,通过有效的差异特征提取和增强,显著提升了小目标的检测精度,特别是在复杂背景和低对比度环境下。该模块通过残差加法和通道与空间注意力机制,增强了可见光与红外模态之间的互补特征交互,减少了冗余信息,提高了检测稳定性。尽管提升了特征交互,CDFIM 仍保持轻量化设计,计算开销和参数量较低,适合实时检测应用。总的来说,CDFIM 模块在保留原始模态信息的同时优化了特征融合,有效提高了 YOLO 在多模态目标检测中的鲁棒性和精度

Ai缝合怪、助力小伙伴高效发论文 132

KMP模板(C++)

这是一个KMPC++的模板。相信很对同学看了大佬超详细的讲解(本文有链接),但还是不太清楚next数组的意义,或者为什么next[0]=-1,而不是1。Kmp的时间复杂度为什么是线性的

卖炫迈的小男孩的博客 7383

【即插即用模块】Mamba篇 | CVPR 2025 | MaIR:新型Mamba扫描方式+通道混洗注意力,全任务涨点!

MaIR是一种新型图像恢复模型,通过嵌套S形扫描策略(NSS)和序列混洗注意力(SSA)改进传统Mamba方法。NSS采用条纹区域划分和S形扫描路径,既保留图像局部性又维持空间连续性;SSA通过通道洗牌和门控机制增强特征聚合。该模块创新性地融合多路径选择性扫描、深度卷积和注意力机制,在保持O(N)计算复杂度的同时,显著提升超分辨率和去噪等任务的性能表现(PSNR提升0.2-0.5dB)。代码实现包含特征洗牌、组卷积等关键操作,适用于高分辨率视觉任务,可作为即插即用组件替代传统自注意力模块。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 1168

KMP hihoCoder1015 KMP算法

人太蠢,,看了一天的KMP。。 刚开始看训练指南的,,后来才惊奇的发现原来刘汝佳写的f数组并不是Next数组! 总觉得和之前看过的完全不一样。。。 后来又百度了一下KMP,研究了很久,然后用自己的逻辑写了一份 http://blog.chinaunix.net/uid-23767307-id-5033555.html 这个人把KMP大篇幅的讲了,,大家可以看看。。 个人认为

qwb的博客 1947

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

KMP算法(学习笔记)

KMP算法总结(南昌理工ACM集训) (这几天想题目想的脑壳疼) 什么是KMP算法 (我准备引用别人的话,讲滴非常好) Knuth-Morris-Pratt字符串查找算法(简称为KMP算法,0.0)可在一个主文本字符串S内查找一个词W的出现位置。 此算法通过运用对这个词在不匹配时本身就包含足够的信息来确定下一个匹配将在哪里开始的发现,从而避免重新检查先前匹配的字符。 为什么我们要用KMP算法呢 我们先介绍一下普通匹配字符串的算法 题目 给定一个模式串S,以及一个模板串P,所有字符串中只包含大

有趣的博客 3454

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

下标从1和0开始的kmp算法模板

acwing kmp 题目描述 给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字。 模板串P在模式串S中多次作为子串出现。 求出模板串P在模式串S中所有出现的位置的起始下标。 输入格式 第一行输入整数N,表示字符串P的长度。 第二行输入字符串P。 第三行输入整数M,表示字符串S的长度。 第四行输入字符串M。 输出格式 共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间用空格隔开。 数据范围 1≤N≤10^4 1≤M≤10^5 输入样例 3 aba 5 .

a599s的博客 1387

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

KMP算法

KMP算法 给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字。 模板串P在模式串S中多次作为子串出现。 求出模板串P在模式串S中所有出现的位置的起始下标。 输入格式 第一行输入整数N,表示字符串P的长度。 第二行输入字符串P。 第三行输入整数M,表示字符串S的长度。 第四行输入字符串S。 输出格式 共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间用...

Axelrod的博客 192

AcWing - KMP字符串(KMP)

题目链接:https://www.acwing.com/problem/content/description/833/ 时/空限制:1s / 64MB 题目描述 给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字。 模板串P在模式串S中多次作为子串出现。 求出模板串P在模式串S中所有出现的位置的起始下标。 输入格式 第一行输入整数N,表示字符串P的长度...

ityanger的技术栈 2821

KMP模板

KMP模板 代码解释

张之海的博客 547

KMP模板代码

终于自己根据理解,手搓了一个自己的AC代码模板了,,,真不容易,,小细节还是有的,而且跟网上的模板普遍存的不是很一样,next[i]表示第i个位置匹配完了,第i+1个位置要匹配的位置 例:ababa  第二个a的next值是2,表示第二个a与第一个a可以匹配上,下一个要看的位置就是第一个b,是否匹配   不过只判是否存在字串,有函数可以用,也是很爽的。 模板代码: void getne...

AAAAAAAC的博客 273

自己的KMP模板

这份模板是我自己在

509

【模板题】KMP字符串

【题目描述】 给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字。 模板串P在模式串S中多次作为子串出现。 求出模板串P在模式串S中所有出现的位置的起始下标。 【输入格式】 第一行输入整数N,表示字符串P的长度。 第二行输入字符串P。 第三行输入整数M,表示字符串S的长度。 第四行输入字符串S。 【输出格式】 共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间用空格隔开。 【数据范围】 1≤N≤1e5 1≤M≤1e6 【输入样例】 3 aba 5 ababa

一只快乐的小蒟蒻~ 254

HHUOJ 1633 算法4-7:KMP算法中的模式串移动数组

HDUOJ 1633 算法4-7:KMP算法中的模式串移动数组 题目链接 题目描述 字符串的子串定位称为模式匹配,模式匹配可以有多种方法。简单的算法可以使用两重嵌套循环,时间复杂度为母串与子串长度的乘积。而KMP算法相对来说在时间复杂度上要好得多,为母串与子串长度的和。但其算符比较难以理解。 在KMP算法中,使用到了一个next数组。这个数组就是在比较失配时母串指针不必回溯,而子串指针移动相应位置即可。我们给出书中next数组的算式表示以及算法,请你实现之。 输入 一个模式串,仅由英文小写字母组成。长度不大

旺崽的博客 2917

KMP算法的理解+板子

其实,我们一开始定义next数组的时候,单纯的希望它有一个功能,就是如果文本串和模板串发生不匹配,那么指针j 去往的地方是 next[j-1]。next[k] 的值和 “在模板串中从0开始到下标为k的字符串中,最长相等前后缀“ 的长度相等。如果i , j 匹配不成功,那么我们希望 j能重新跳到模板串的某一个位置,重新开始匹配。如果i,j匹配, 那么说明 [0,j-1]肯定是匹配上了的,又[0,j-1]的长度是 j。那么当i,j匹配的时候,我们就用第二条性质,直接让next[i] = j+1.

louisdlee的博客 639
上一篇: L3-2 至多删三个字符
下一篇: L1-046 整除光棍 (20分)
zhbbbb!
博客等级 码龄7年 43粉丝 71原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值