KMP算法(Knuth-Morris-Pratt字符串查找算法)

KMP查找算法 第一行输入测试案例数目,接着每个案例第一行输入字符串长度,第二行为字符串;第三行为目标字符串长度,第四行为目标字符串。输出为目标字符串出现次数。 立即下载

KMP算法的全称为Knuth-Morris-Pratt字符串查找算法,是可以在文本串s中快速查找模式串p的一种算法。

在详细讲解KMP算法之前,首先讲解一下暴力匹配。暴力匹配就是逐字符逐字符地进行匹配(比较s[i]和s[j]),如果当前字符匹配成功(s[i]==s[j]),就匹配下一个字符(i++;j++;);如果匹配失败的话,就回溯(i=i-j+1;j=0;)。这样的算法时间复杂度是 O ( n m ) O(nm) O(nm)。

从上面可以看出暴力匹配算法,每次都会回溯到刚开始匹配的下一个字符,这样比较耗时,如果我们跳过之前匹配的字符从匹配失败的位置重新匹配,这样会出现缺漏。

为了解决这个问题,研究者引入了PMT(Partial Match Table,部分匹配表)。下一次j应该赋什么值只与模式串自身有关,即每个字符串都会对应一张PMT表。PMT中的pmt数组中位置i的内容是,从p[0]往后数、同时从p[i]往前数相同的位数,在保证前后缀相同的情况下,最多能数多少位。

KMP算法具体的匹配过程以ababcabaa为例:

在这里插入图片描述

在匹配字符串的过程中,当我们在匹配j=8时发现s[i]与p[j]不相等,则会令j=pmt[j-1]=pmt[7]=3重新进行匹配,若此时s[i]与p[j]仍不相同,则继续令j进行回退。直至j回退到0处且仍不匹配时,我们不再令j回退,而选择移动i。

具体的KMP算法的正确匹配过程请阅读文献1。

KMP代码实现为:

public int strStr(String s, String p) {
    int n = s.length(), m = p.length();
    char[] cs = s.toCharArray(), cp = p.toCharArray();
    int[] next = next(p);

    for (int i = 0, j = 0; i < n; i++) {
        while (j != 0 && cs[i] != cp[j]) j = next[j - 1];
        if (cs[i] == cp[j]) j++;
        if (j == m) return i - j + 1;
    }

    return -1;
}

PMT表的生成过程,如果使用暴力的话,时间复杂度会是 O ( n 2 ) O(n^2) O(n2)。这种做法复杂度较高,因此我们采用更精妙的做法,错开一位后,让p自己匹配自己,即用前缀去匹配后缀。其具体过程为下图所示:

在这里插入图片描述

PMT数组生成的代码为:

public int[] next(String p) {
    int m = p.length();
    int[] pmt = new int[m];

    char[] cs = p.toCharArray();

    for (int i = 1, j = 0; i < m; i++) {
        while (j != 0 && cs[i] != cs[j]) j = pmt[j - 1];
        if (cs[i] == cs[j]) j++;
        pmt[i] = j;
    }
    return pmt;
}

题目链接

  1. 数组和字符串-实现 strStr()

参考文献:

  1. 算法学习笔记(13): KMP算法
KMP查找关键字 利用KMP算法进行关键字查找,任意输入关键字用来进行查找。 立即下载

相关推荐

PLL锁相环性能上不去?可能是电荷泵的电流失配在捣鬼(附Jae-Shin Lee经典方案解析)

本文深入分析了PLL锁相环性能瓶颈的根源——电荷泵电流失配问题,详细解析了Current Mismatch和Current Deviation的区别及其对系统的影响。重点介绍了Jae-Shin Lee的多级电流镜技术,该方案通过运放构建虚拟短路和四级电流镜结构,显著降低了电流失配,使参考杂散改善15dB以上。文章还提供了从仿真到流片的完整优化流程,帮助工程师系统解决电荷泵性能问题。

weixin_30684743的博客 369

118-串匹配的KMP算法的实现

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> void GetNext(const char *p, int *next)//获取k的值 { next[0] = -1; next[1] = 0; int lenp = strlen(p); int i = 1; int k = 0; while (i + 1 < lenp) { ..

LINZEYU666的博客 454

利用GPAC生成MP4文件

GPAC主要针对学生和内容创作者,代表了一个跨平台的多媒体框架,开发人员可以使用它在 LGPL 许可下制作开源媒体。GPAC多媒体框架兼容范围广泛的流行文件类型,从常见格式(如 AVI、MPEG 和 MOV)到复杂格式(如 MPEG-4 系统或 VRML/X3D)和 360 电影。

深之JohnChen的专栏 1770

KMP-字符串查找算法

问题:假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢?即2层循环,太过复杂。

禊月初三的博客 1446

量化策略分享之首板低开

这个量化策略的核心是选择在低位、首次涨停后次日低开的股票,开盘时买入,上午有盈利就卖出,没有就拿到尾盘在卖出;策略优点在于选择的股票在低位,风险较低,并且刚启动首板,有大资金介入,第二天能快速跑路。

qq_29301281的博客 1463

KDD 2025 | 人大团队提出多任务贝叶斯联邦学习算法,同时处理分类和回归

©PaperWeekly 原创 ·作者 |吕俊良单位 |中国人民大学统计学院本文介绍了中国人民大学统计学院的一篇关于多任务贝叶斯联邦学习的文章“Task Diversity in Bayesian Federated Learning: Simultaneous Processing of Classification and Regression”,本文被 KDD 2025 接收,代码已经...

Paper weekly 2746

子串查找算法KMP

KMP算法(Knuth-Morris-Pratt算法)是一种高效的字符串匹配算法,由Donald Knuth、James H. Morris和Vaughan Pratt在1977年共同发明。它通过利用已经部分匹配这个有效信息,避免了暴力匹配中的大量回溯,从而显著提高了匹配效率。预处理模式串,生成部分匹配表(next数组)。利用这个表在匹配失败时快速滑动模式串,减少不必要的比较。预处理阶段:计算模式串的部分匹配表。匹配阶段:利用部分匹配表进行快速匹配。

xy2006860的专栏 1538

revit二次开发环境搭建(2024版)(小白友好)

revit二次开发环境配置,SDK、addin manager和lookup新手友好安装教程

m0_56961251的博客 1419

【算法图文动画详解系列】KMP 字串匹配搜索算法

问题描述:字串匹配搜索 假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢? 暴力匹配算法 如果用暴力匹配的思路,并假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置,则有: 1、如果当前字符匹配成功(即S[i] == P[j]),则i++,j++,继续匹配下一个字符; 2、如果失配(即S[i]! = P[j]),令i = i - (j - ...

AI天才研究院 8985

Day 01: 与Python的第一次亲密接触

环境搭建 、第一个程序 Hello, World!、以及Python之禅 (The Zen of Python) 的解读。

杨小扩的博客 220

微信小程序 - 详细实现随机生成订单号,微信小程序创建订单号思路,不重复订单号生成的方法,小程序自动生成固定规则的订单号流水号(必须是唯一不重复的订单号,生成唯一订单号)详细生成方法,示例代码教程最新

微信小程序,vue2,vue3,订单号,流水号思路,微信小程序 详细实现随机生成订单号(JavaScript),随机生成商户订单号,根据当前时间随机生成流水号或者订单号,微信小程序之商家订单,订单号随机生成器,自动生成固定规则的订单号(前缀+采购日期+6位流水号)微信小程序 生成外卖顺序号,生成订单号或流水号简单方法,实现订单号生成唯一的解决方案,如何按日期生成订单号,14位编号=8位日期(+6位流水号),自动生成订单号(固定+日期+数字),销售订单号自动生成。在微信小程序开发中,详解实现随机生成创建订单号

🏆 前端领域优质创作者 1185

KMP算法--子串查找问题

kmp算法

小青菜的博客 2544

踩过20+工控视觉项目的坑后,我用C# + 海康相机 + YOLOv11实现了零依赖产线缺陷检测

触发式检测:只有光电传感器检测到零件到位,才触发相机拍照和算法检测,不是持续推理,减少工控机性能占用;全链路本地运行:从图像采集、算法推理到不良品剔除,所有逻辑全在本地工控机运行,不需要外网、不需要云端服务,哪怕产线断网也能正常运行;异常降级机制:算法推理异常时,系统自动触发产线缓停,同时声光告警,不会让不良品流到下工序,满足汽车行业IATF16949质量要求;模块化解耦:算法核心层和业务逻辑层完全分离,后续更换YOLO模型、新增缺陷类型,只需要替换模型文件,不需要修改业务逻辑;全链路可追溯。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 152

KMP算法——Knuth-Morris-Pratt 字符串查找算法

KMP算法——个人学习记录

weixin_65771125的博客 1019

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

efm32 入门.pdf

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

KMP算法 Knuth-Morris-Pratt 字符串查找算法

Knuth-Morris-Pratt 字符串查找算法(常简称为 “KMP算法”)是在一个“主文本字符串”S 内查找一个“词”W 的出现,通过观察发现,在不匹配发生的时候这个词自身包含足够的信息来确定下一个匹配将在哪里开始,以此避免对以前匹配过的字符重新检查。--Wiki定义 这个算法乍看不难,细细考虑起来,却是很难的算法,网上有很多介绍了,我在这里也不重复啰嗦,贴出参考资料,然后给出我自己的例子...

架构设计 469

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

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

KMP(Knuth-Morris-Pratt) 字符串查找算法

深入理解 KMP(Knuth-Morris-Pratt)算法 。以力扣28题. 实现 strStr()为例,详细讲解。 期待与每一位逐梦路上的同学一起进步、成长。

weixin_44214900的博客 529

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

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

【算法图文动画详解系列】KMP 字符串查找算法(Knuth-Morris-Pratt )

问题描述:字串匹配搜索假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢?暴力匹配算法如果用暴力匹配的思路,并假设现在文本串S匹配到 i 位...

AI天才研究院 8856

【数据结构与算法】Knuth-Morris-Pratt 算法(KMP算法):一种在字符串中查找子串的算法

KMP(Knuth-Morris-Pratt)算法是一个在字符串中查找子串的算法,由 Donald Knuth、Vaughan Pratt 和 James H. Morris 共同发明。这个算法的特点是在查找过程中,不会回溯主串,也不会重复扫描已经比较过的子串,因此它的时间复杂度是线性的。它的主要优点是在比对过程中,当一个字符不匹配时,可以跳过一些无需再次比对的字符,从而提高匹配效率。

HEX9CF的技术博客 1483

数据结构-KMP 算法(Knuth-Morris-Pratt 字符串查找算法)

1.什么是KMP算法:快速的从一个主串中找出一个你想要的子串 KMP算法是一种改进的字符串匹配算法。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。 首先,对于这个问题有一个很单纯的想法:从左到右一个个匹配,如果这个过程中有某个字符不匹配,比较指针就跳回去(比较指针回溯),将模式串向右移动一位。 /** * 暴...

m0_54923920的博客 1022

KMP- Knuth-Morris-Pratt 字符串查找算法

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33860528的博客 122

KMP(Knuth-Morris-Pratt)字符串查找算法 && BM(Boyer-Moore)算法 && Sunday算法

KMP算法步骤KMP完整代码模板BM算法原理BM算法代码实现坏字符好后缀完整代码Sunday算法原理代码模板 KMP算法 KMP的匹配是从模式串的开头开始匹配的 步骤 ①寻找前缀后缀最长公共元素长度 如果给定的模式串是:“ABCDABD”,从左至右遍历整个模式串,其各个子串的前缀后缀分别如下表格所示: ②求next数组 找最大对称长度的前缀后缀,然后整体右移一位,初值赋为-1(当然,你也可以直接计算某个字符对应的next值,就是看这个字符之前的字符串中有多大长度的相同前缀后缀)。 ③根据next数.

qq_52317884的博客 644

Knuth-Morris-Pratt算法(KMP)

Knuth-Morris-Pratt 字符串查找算法(常简称为 “KMP算法”)是在一个“主文本字符串”S 内查找一个“词”W 的出现,通过观察发现,在不匹配发生的时候这个词自身包含足够的信息来确定下一个匹配将在哪里开始,以此避免对以前匹配过的字符重新检查。 举个例子: leetcode中28. Implement strStr() 返回在haystack中第一次出现Needle的索引,如果...

Jeff_的博客 2311

KMP(Knuth-Morris-Pratt)字符串精确查找匹配算法~代码笔记

针对模式串,长度为m,计算next[0]~next[m-1]数组。其中利用i为模式串中字符索引位置,即从0到(m-1);len为子字符串(模式串从0到i截取的子字符串)前后缀相等的字符串最大长度,赋值为next[i]。有初始值next[0] = 0,即单个字符的前后缀相等长度为0。前缀从第一个字符开始不包含最后一个字符如“abc”,前缀有“a”,"ab";后缀从最后一个字符开始不包含第一个字符如“abc”,后缀有“c”,"bc";数组,当在不匹配时,能够直接跳跃式查找下一次匹配起点,提高了匹配效率。

从小菜到大鸟的博客 381

什么是KMP算法

定义 Knuth-Morris-Pratt 字符串查找算法,简称为KMP算法,常用于在一个文本串 S 内查找一个模式串 P 的出现位置。 这个算法由 Donald Knuth、Vaughan Pratt、James H. Morris 三人于 1977 年联合发表,故取这 3 人的姓氏命名此算法。 下面直接给出KMP算法的操作流程: 假设现在文本串 S 匹配到 i 位置,模式串 P ...

邵光亮的博客 2366
上一篇: 快速排序(Quick Sort)
下一篇: 最大公约数和最小公倍数(GCD & LCM)—简写版
小菜2小白
博客等级 码龄4年 4粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值