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

ONNC Open Neural Network Compiler 开源神经网络编译器 一个 开源、模块化、可重用编译器算法和工具链的库,专门针对深度学习加速器(DLA)部署导入ONNX模型 ONNC是一个集合了开源、模块化、可重用编译器算法和工具链的库,专门针对深度学习加速器(DLA)。ONNC从底层开始构建,旨在将ONNX中间表示(IR)翻译成专有DLA代码。其软件架构设计强调可移植性和可重用性,从而简化了开发新后端的工作。上图展示了ONNC软件栈的顶层框图。软件栈从导入ONNX计算图模型到输出相应的硬件二进制文件,展示了各个功能块。 阅读详情

相关推荐

反制反心理特征的研究

抓牛股

m0_58032574的博客 908

kmp算法模板

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

m0_73635448的博客 771

3DSlicer冠脉分割实战:从DICOM导入到三维重建的完整流程(附常见问题解决)

本文详细介绍了使用3DSlicer进行冠脉分割的完整流程,从DICOM数据导入到三维重建,涵盖环境配置、视图优化、心脏区域分割及冠脉精细分割等关键步骤。针对常见问题提供实用解决方案,帮助医学影像从业者高效完成心血管结构分析,提升诊断准确性。

weixin_29271053的博客 630

KMP 算法详解

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

这里是阿安的博客 5万+

告别零散脚本:用Playwright+Pytest+Yaml+Allure搭建可维护的UI自动化项目

UI自动化测试是软件质量保障的关键环节,其核心在于模拟用户操作,对Web应用界面进行功能验证。传统的脚本堆砌方式常因代码耦合度高、维护成本大而难以为继。工程化解决方案通过分离关注点,将测试逻辑、数据和配置解耦,从而显著提升项目的可读性、可维护性和可扩展性。其技术价值在于构建可持续运行的自动化资产,而非一次性脚本。典型的应用场景包括Web应用的回归测试、兼容性测试及CI/CD流水线中的质量门禁。本文以Playwright、Pytest、Yaml和Allure为核心技术栈,详细阐述了如何从项目架构、页面对象模型

weixin_42529328的博客 300

ERA5数据驱动WRFV4.4实战:单层嵌套配置与关键报错排查指南

本文详细介绍了使用ERA5再分析数据驱动WRFV4.4模式进行单层嵌套模拟的完整实战流程。内容涵盖从数据精准下载、WPS前处理配置、WRF核心参数设置到高频报错的深度排查与解决方案,旨在帮助初学者在有限服务器资源下,高效完成WRF模拟并规避常见陷阱。

q5r6s7的博客 770

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

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

xhd0728的博客 3011

Lattice CrosslinkNx LIFCL-40实战解析:MIPI D-PHY硬核IP配置与CSI-2数据解析全流程

本文详细解析了Lattice CrosslinkNx LIFCL-40 FPGA中MIPI D-PHY硬核IP的配置与CSI-2数据解析全流程。通过实战案例,介绍了硬件环境搭建、寄存器配置、数据包结构解析及视频流重构技巧,帮助开发者快速掌握高速图像采集系统的设计与优化方法。

weixin_29159613的博客 200

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

基于SpringBoot 3 + Vue 3的全栈民宿预约管理系统设计与实现

文章将详细阐述系统的需求分析、架构设计、数据库设计、核心功能模块的实现(包括用户认证、房源管理、订单流程、支付集成等),并提供关键代码片段,最后对系统进行总结与展望。.requestMatchers("/api/admin/**").hasRole("ADMIN") // 管理员接口。.requestMatchers("/api/auth/**").permitAll() // 认证接口公开。.requestMatchers("/api/public/**").permitAll() // 公开资源。

2201_76125393的博客 272

Vue+OpenLayers:解决中国境内OpenStreetMap地图加载问题

然而,在使用OpenLayers和Vue框架搭建地图应用时,很多中国开发者可能会遇到一个常见问题:OpenStreetMap(OSM)地图无法正常加载。为了解决这个问题,我们可以使用其他方式获取地图数据,比如使用国内的地图服务提供商。通过使用国内地图服务商提供的地图数据,我们可以解决OpenStreetMap地图加载问题。然后,我们创建一个OpenLayers地图对象,并指定地图图层的源为国内地图服务商提供的地图URL。属性,可以将地图的中心点和缩放级别调整到我们需要的位置。

CodeWhizZ的博客 8275

KMP模板(C++)

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

卖炫迈的小男孩的博客 7383

130、NPU的仿真测试:使用Gem5进行全系统仿真

这篇文章摘要(149字): 本文分享了使用Gem5全系统仿真器验证NPU设计的实践经验。作者通过搭建自定义NPU模型并集成到Gem5系统中,实现了CPU-NPU-内存协同仿真。关键点包括:1) 使用SimObject机制构建可配置的NPU模型;2) 合理配置IO和内存总线避免访问冲突;3) 开发Linux驱动实现CPU与NPU通信;4) 利用Gem5调试功能监控内部状态。相比RTL仿真和FPGA验证,该方法能快速验证微架构设计并定位系统级问题,有效减少了流片风险。文章特别强调了时钟域配置、总线仲裁、对齐访问

m0_50546716的博客 122

KMP hihoCoder1015 KMP算法

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

qwb的博客 1947

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

KMP算法(学习笔记)

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

有趣的博客 3454

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

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

下标从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

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

余额充值