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模板

这20个网络工程项目经验,帮我跳槽加薪不止一次 嘿,大家好,我是圈圈,一个在网络工程圈子里混了十多年的老鸟。从国企的网管起步,到现在给大厂做顾问,我见过太多简历:有的光鲜亮丽,证书一堆,但一聊项目,就露怯;有的简历朴实,但列出的项目经验让人眼前一亮,直接拿offer。为什么?因为招聘官最看重实战。理论谁都会背,项目经验才是你的“硬通货”。尤其在网络工程这行,项目不光证明你的技能,还展示你解决问题的能力。今天,我就分享20个我亲身经历或见过的网络工程项目经验。每个都值得写进简历,不是吹牛,这些项目帮我跳槽加薪不止一次。 阅读详情

相关推荐

W25N01GV SPI NAND Flash驱动开发避坑指南:详解2KB缓冲区机制与状态寄存器正确用法

本文深入解析W25N01GV SPI NAND Flash芯片的2KB缓冲区机制与状态寄存器正确用法,提供STM32 HAL和ESP-IDF项目的实战解决方案。涵盖双阶段操作原理、状态寄存器深度解析、时序控制优化及跨平台驱动设计要点,帮助开发者避免常见错误并提升存储性能。

aizhouqian5537的博客 640

kmp算法模板

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

m0_73635448的博客 771

BIOS更新后PIN不可用怎么办?从原理到实操的完整修复指南

在计算机维护中,BIOS更新是常见的固件升级操作,但其引发的登录异常却常让用户措手不及。Windows Hello PIN并非传统密码,它通过TPM芯片与设备启动环境(PCR状态)强绑定,一旦主板固件或安全启动配置改变,TPM便会拒绝释放密钥,导致“由于此设备上的更改,你的PIN不再可用”。理解这一原理后,恢复路径清晰可控:优先尝试密码登录,或通过WinRE替换utilman.exe创建临时管理员,必要时还需处理BitLocker恢复密钥。本文面向系统维护与数据安全场景,系统梳理PIN失效的恢复流程与避坑方

weixin_31364787的博客 377

KMP 算法详解

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

这里是阿安的博客 5万+

期末求生指南:手把手教你用F12开发者工具绕过百一测评的切屏检测(JavaScript/jQuery实战)

本文详细介绍了如何利用F12开发者工具绕过百一测评的切屏检测,通过分析JavaScript/jQuery中的blur()和focus()事件监听机制,提供实战技巧动态修改代码。文章涵盖事件监听定位、代码修改方法及应对高级检测机制的策略,适合需要临时解决线上考试限制的学生参考。

weixin_30731305的博客 448

2019年电赛D题《简易电路特性测试仪》全过程

2019年全国大学生电子设计大赛D题《简易电路特性测试仪》硬件部分及故障分析

zzhao2580的博客 5万+

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

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

xhd0728的博客 3011

1、初探 Tiny Machine Learning

Tiny Machine Learning(TinyML)是机器学习与嵌入式系统的融合领域,致力于在资源受限的微控制器上运行AI模型。本文介绍了机器学习基础、TinyML的核心概念、应用领域(如智能家居、工业物联网、医疗保健)、面临的挑战(如资源限制、模型压缩、数据质量),以及从硬件准备到模型部署的实践步骤。通过利用训练与推理的资源不对称性,可在PC上训练模型并部署至低功耗设备进行实时推理,推动边缘智能的发展。

loss4bartender的博客 123

【算法】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

【ZYNQ】VDMA 的使用

VDMA, Video Direct Memory Access 是 Xilinx 官方提供的高速内存存取 IP,采用 AXI4-Stream 与 AXI4 协议实现存储映射接口(Memory Map)与非存储映射接口(Non-Memory Map)接口的转换,主要用于视频数据缓存,同时提供帧缓存与帧同步控制功能。本文主要介绍 AXI VDMA 的配置与使用方法。

洋洋Young的博客 1581

如何借助GPT- 6 写好一篇论文:从引言到参考文献完整步骤(附专业提示词)

七哥就结合这篇文章的写作思路,依次拆解引言、方法、结果、讨论、摘要、标题和参考文献分别应该怎么写,同时也聊聊,在每一个环节里,我们可以怎样合理借助 GPT-6,让论文写作变得更清晰、更高效。可以和七哥交流学术写作或Gemini、GPT、Claude 等大模型 学术实操相关问题,多多交流,相互成就,共同进步。8、不修改、不补写、不猜测任何样本量、阈值、剂量、设备型号、参数或统计方法,所有缺失但影响方法完整性的信息统一标记为【待作者确认】、检查方法中设定的每一个分析项目能否在后续结果章节找到对应位置。

智能AI让学术科研更容易 113

KMP模板(C++)

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

卖炫迈的小男孩的博客 7383

基于Matlab的磁力计校准(附源码)

磁力计沿传感器的 X、Y 和 Z 轴检测磁场强度。精确的磁场测量对于传感器融合以及确定航向和方向至关重要。为了用于航向和方向计算,需要校准典型的低成本MEMS磁力计,以补偿环境噪声和制造缺陷。一、理想磁力计理想的三轴磁力计沿正交 X、Y 和 Z 轴测量磁场强度。在没有任何磁干扰的情况下,磁力计读数测量地球磁场。如果在传感器通过所有可能的方向旋转时进行磁力计测量,则测量值应位于球体上。球体的半径是磁场强度。要生成磁场样本,请使用对象。出于这些目的,可以安全地假设每个方向的角速度和加速度为零。

珞瑜的博客 4520

KMP hihoCoder1015 KMP算法

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

qwb的博客 1947

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

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

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

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、付费专栏及课程。

余额充值