KMP 牛人讲解

KMP算法原理及实现分析 KMP算法分析 一、先来看看传统的暴力解法 1.1 BF算法设计思想 1、主串和模式串逐个字符进行比较 2、当出现**「字符串不相同」时,也就是「失配」**时,主串的比较位置重置为起始位置的下一个字符位置,模式串的比较位置重置为起始位置 1.2 BF算法的设计缺陷及解决方案 在BF算法中,每次失配都需要回溯指向上次比较起始字符的下一个字符。通过观察发现:在回溯的时候,已匹配似乎**「有一部分」没必要继续比较了,这样可以降低算法的「时间复杂度」** 2.1 KMP算法设计思路 在匹配过程中出现字符比较不 阅读详情

KMP算法

我们从一个普通的串的模式匹配算法开始讲起,这样你才能更深入的了解KMP算法及其优点。
咱们先来看看普通的串的模式匹配算法是怎么进行比较的

主串 (S) a b a b c a b c a c b a b
子串 (T)a b c a c       (子串又被称为模式串)

红色表示当前这趟比较指针所在位置,兰色表示当前这趟比较中匹配的部分

第一趟(详细过程)

a b a b c a b c a c b a b
a b c a c


a b a b c a b c a c b a b
a b c a c


a b a b c a b c a c b a b
a b c a c
遇到不匹配的地方时指针回朔,子串向前移动一位(下同),变成如下形式

a b a b c a b c a c b a b
a b c a c

第二趟(省略了中间阶段指针移动比较过程,下同)

a b a b c a b c a c b a b
      a b c a c

第三趟

a b a b c a b c a c b a b
      a b c a
c

第四趟

a b a b c a b c a c b a b
           a b c a c

第五趟

a b a b c a b c a c b a b
               a b c a c

第六趟

a b a b c a b c a c b a b
               
a b c a c _
完成匹配,跳出

这就是普通算法的详细匹配过程,看明白了算法就简单了
详细算法我现在就不给了,等以后有时间再编辑。不过假如串的长度为m,子串的长度为n的话,那么这个算法在最坏的情况下的时间复杂度为O(m*n) ,有没有办法降低它的时间复杂度呢?(废话,当然有拉,不然回这个帖子干什么)

-----------------------------
拜D.E.Knuth 和 J.H.Morris 和 V.R.Pratt     所赐,我们有了一种时间复杂度为O(m+n)的算法,为了纪念这3位强人为计算机科学所做的贡献,分别取这3位先生的名字的首写字母K,M,P来命名这个算法,即著名的KMP算法。

我们先不管这个KMP算法是什么,我们先来看看我们能够想到怎样的方法来改进上面的普通算法。

通过观察,我们发现一个问题,如果一个子串,假设为a b c d e f , 兰色的部分与主串匹配, 红色的f 与主串不匹配,那么这个子串最多能往右边移动几位呢?因为子串中的第一个字符 a!=b !=c !=d !=e !=f ,那么主串中与b c d e 匹配的部分肯定和a不匹配。而与
f不匹配的那部分无法判断与a是否匹配。因此子串最多向右移动5位,即a移动到f所在的位置上,再进行判断。

在解决这个问题的同时,我们又发现了一个问题,当这个子串为a b c d a f 时又会如何呢?因为无法判断主串中与a匹配对应的位置开始往后的部分是否与整个子串相匹配,所以子串最多向右移动4位,即a移动到a的位置上,然后再进行判断。

按照这个方法,我们再来看看前面我们举的例子。

第一趟

a b a b c a b c a c b a b
a b c a c

第二趟

a b a b c a b c a c b a b
      a b c a c

第三趟

a b a b c a b c a c b a b
               a b c a c _
完成匹配,跳出

是不是简单多了呢?这个方法不困难吧,也很容易理解吧。
事实上这就是很多人大叫困难的KMP算法的最基本也是最核心的方法

你现在是不是在想 如果我早生50年,KMP算法就要改名了呢?

当然,强人们的思维比我们严密多了,他们考虑的更完全,比如象 a b c d e a b c     ,这种字符串相同的情况,当然这种情况并不比单个字符相同的情况复杂多少。在思想上KMP算法与上面我们讲的方法完全一致,都是要让子串向右移动尽可能远的一段距离来达到降低时间复杂度的目的,但在具体操作上KMP算法与上面的方法又有所不同。他们为子串引入了一个参数next[ j ] ,我们先来讲下next[j] 怎么求:

假设子串为 'p1 p2 p3 p4.......pm '
对于第j个字符,有next[ j ] =  
(1)      0       (j=1)
(2)      Max{ k | 1<k<j     &&     ' p1...p k-1 '     = ' p j-k+1...p j-1 ' }
(3)      1       其他情况

没有大括号就是不方便。哎,上面的算式是不是把你弄晕了呀?没关系,下面我介绍一种偷懒的方法

我就以

子串        a b a b a a b a b
next[j]      0 1 1 2 3 4 2 3 4

为例 来讲下
next[j] 里面 开头的红色01 是固定格式.

我就以兰色的4 来说明下为什么是4.
与4有关的, 是4所对应的兰色a之前的所有的字符,即紫色的 a b a b a
这个字符串中所有符合匹配条件的字符串如下
a b a b a                a b a b a
a
                                         a
a b                                   b a (不符合,舍去)                                                                                       

a b a                             a b a       最长的匹配字符串(a b a b a本身除外)在这里 ,长度为3, 再加上1,就是4了
注意next[ j ]中4 的位置!
next[ j ]中其他位置的数值也可以用同样的方法得出

为什么next[j]开头为固定的01?这个问题不太好回答。
最开头的next[j]是由子串第一个字符前面的字符来决定的,但那不存在,因此第一个next[j]的值为0
第二个next[j]是由第一个字符决定的,由于他是自己与自己比较,一定相等,所以值为1。
这样说可能有点牵强。那么我们来看看下面,可能会明白些,也更加了解next[j]到底是起什么作用的。

子串                      a b a b a a b a b
next[j]                   0 1 1 2 3 4 2 3 4
匹配子串长度       1 2 3 4 5 6 7 8 9      (对应位置     也可看成是截止到当前字符的子串串长)
最大右移              1 1 2 2 2 2 5 5 5      (当前字符不匹配时,子串最大右移距离)

我们发现,最大右移 + 对应的next[j] = 匹配子串长度,我估计这就是为什么要引入next[ j ] 这个参量,为了方便计算最大右移。不过对于next[j]的官方具体定义我没找到,望高人相告,在下先谢过了。

事实上,KMP算法还是有改进余地的,我们一直都在避免讨论这样一种情况:

a b c d e a
0 1 1 1 1 1
当a不匹配时,能向右最大移动几位呢?答案是6位,a 所能移动到的位置为a的下一位,即a 的右边一位
而根据next[j]计算出子串最大右移为6-1=5。这里他将a移动到a的位置上,然后做了一次无意义的比较(a = a     ,a 与主串不匹配,那么显然a 与主串也不匹配)。这个问题我就不说了,虽然我有个改进方法,但这个问题还是留给大家去思考吧。

交货单冲销发货过账的正确姿势:用 VL09 与 ABAP 批量反冲 Goods Issue 摘要 本文详细解析了SAP系统中VL09事务码的技术实现与业务应用。VL09用于反冲发货的货物移动,通过标准冲销路径(移动类型602冲销601)确保单据链路一致、状态机正确回退和业务规则生效。文章对比了经典VL09与Fiori应用在不同SAP产品形态中的位置,并针对STO场景提供了ME23N验证方法。核心内容包括WS_REVERSE_GOODS_ISSUE函数模块的调用要点、必须COMMIT的原因(SAP LUW机制),以及处理Handling Unit等限制条件的注意事项。最后给出了将VL09工程化的项目 阅读详情

相关推荐

使用Dify打造视频生成工作流:从提示词到视频的完整指南

Dify作为开源LLM应用开发平台,通过可视化工作流编排实现从文本到视频的端到端生成,将创意周期从天级缩短至分钟级。核心流程包括提示词工程、视频API调用、存储分发和结果反馈。

牛奶夹心巧克力 3429

20200922 001_经典算法面试题1——字符串匹配之KMP算法

20200922 001_经典算法面试题1——字符串匹配之KMP算法 转载:https://blog.youkuaiyun.com/v_july_v/article/details/7041827 1. 字符串匹配问题: 1)有一个字符串 str1= "BBC ABCDAB ABCDABCDABDE",和一个子串 str2="ABCDABD" 2)现在要判断 str1 是否含有 str2, 如果存在,就返回第一次出现的位置, 如果没有,则返回-1 3)要求用最快的速度来完成匹配 4)你的思路是什么? .

qq_39696269的博客 3107

VOS3000线路对接、路由配置与路由分析操作教程

通过本教程,你应该已经掌握了VOS3000的线路对接、路由配置和路由分析的基本操作。添加备用路由:为常用前缀添加备用路由,确保在主路由失效时呼叫仍能正常进行。进入线路管理:点击“系统管理” -> “线路管理” -> “添加线路”。查看日志:在“系统日志”中查看路由选择情况,确保路由配置正确。失败原因:查看失败呼叫的原因(如“无应答”、“线路忙”等)。线路选择:选择之前添加的线路(如“供应商A”)。保存并启用:填写完毕后,点击“保存”并启用路由。路由名称:自定义一个名称(如“路由A”)。

AI_wx_3307623172的博客 2970

kmp算法及其优化

KMP算法及其优化 为什么要使用kmp算法? 传统的字符串模式匹配主串和字串的指针在不匹配时都要重复的进行回退。而有些回退的比较意义不大。这就造成了算法的效率不高。时间复杂度为o(mn)。而kmp算法恰恰就是为了解决这一个问题而产生的。在kmp算法中主串指针不必回退。而下一次用字串的哪个字符去匹配只与字串有关,与主串无关,这也就大大的提高了算法的效率,时间复杂度优化到了o(m+n)。 kmp算法的灵魂(next数组) 手算方式1(好理解方便做题的方式) 也就是说无论字串是什么next[1]的值都是0;

qq_43460059的博客 2644

【STM32篇】DRV8425驱动步进电机

【STM32篇】在上篇文章中使用了HR4988实现了步进电机的驱动,在实际运用过程,4988驱动步进电机会存在电机噪音太大的现象。本次将向各位友友介绍一个驱动简单且非常静音的一款步进电机驱动IC。

we_long的博客 3067

【沃顿商学院学习笔记】商业基础——Financing:05 名义利率和实际利率 APR& EAR

商业基础——名义利率和实际利率 本章主要是从名义利率和实际利率的相关概念和计算方法进行学习。 名义利率和实际利率 APR&amp;amp; EAR 根据下图可以直到: APR,QUOTED RATE在精算中又叫名义利率,比如一个房产贷款quoted rate or APR是12%,且按月复利,那么说明它的月实际利率是12%/12=1% EAR是effecive annual rate,在精算中叫实际利率,...

ECNU乐扣老师——区块链、可计算情感 1万+

KMP算法及优化

KMP算法及优化 今天看到同学在复习数据结构书上的KMP算法,忽然发觉自己又把KMP算法忘掉了,以前就已经忘过一次,看样子还是没有真正的掌握它,这回学聪明点,再次搞明白后记录下来。 一般字符串匹配过程 KMP算法是字符串匹配算法的一种改进版,一般的字符串匹配算法是:从主串(目标字符串)和模式串(待匹配字符串)的第一个字符开始比较,如果相等则继续匹配下一个字符, 如果不相等则从主串的下一个字符开始匹...

qq_45768871的博客 749

Oracle 从入门到精通系列(入门篇)1.1-Oracle 数据库发展史

Oracle 从入门到精通系列(入门篇)1.1-Oracle 数据库发展史

LuciferLiu_DBA 2190

串---KMP算法及其优化实现

通过本文档,您可以了解到 KMP 算法的基本概念和实现方法。使用这些知识,您可以轻松地处理字符串匹配问题,特别是在大数据量的情况下,KMP 算法能显著提升性能。希望这份指南能够帮助您更好地理解和使用 KMP 算法。

KYGALYX的博客 1228

华为OD机试 - 报文响应时间 - 贪心算法、位运算(Python/JS/C/C++ 2024 E卷 200分)

贪心算法是在每一步选择中都做出当前最优的选择,期望通过局部最优解推导出全局最优解的算法。

学Java,找哪吒 1757

史上最全!研究生科研必备科研工具(含AI科研工具),附使用说明和示例

这些工具在科研中的应用非常广泛,可以帮助研究生更高效地完成研究任务。为了更好地利用这些工具,建议深入学习它们的官方文档和教程,或者参加相关的工作坊和培训。

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

KMP算法及优化(串模式匹配 含完整代码)

串的模式匹配其实就是找到子串在主串中的位置。例如:串A='ABCD' 字符B在串A中的位置就是2,串BC在A中的位置就是2。位置不是位序,位置是从1开始。串的结构类似于线性表的顺序存储结构,串是用一组地址连续的存储单元存储串值的字符序列。一般用一个定长的数组来表示串的每个字符分量(为了表示串是从1开始而不是0一般将数组位序为0的位置舍弃):如串中保存串 ABCD。串长有两种表示方法:方法一是使用一个额外的变量len来存放串的长度 如下图方法二是在串值后面加一个不计入串长的结束符“\0”。

m0_60284144的博客 2495

Android 15.0 添加自定义服务,并生成jar给第三方app调用

在15.0系统ROM产品定制化开发中,由于需要新增加自定义的功能,所以要增加自定义服务,而app上层通过调用自定义服务,来调用相应的功能,所以系统需要先生成jar,然后生成jar 给上层app调用,接下来就来分析实现的步骤,然后来实现相关的功能 从而来实现所需要的功能

安卓兼职framework和app工程师的博客 667

牛人对KMP的理解

<br />相当精辟的讲解!以前看算法书没搞懂,今天看了一遍就受益匪浅!<br />来源:(http://blog.sina.com.cn/s/blog_5cf979410100h54g.html) - 牛人对KMP的理解[转]_琥珀_新浪博客<br />我们从一个普通的串的模式匹配算法开始讲起,这样你才能更深入的了解KMP算法及其优点。<br />咱们先来看看普通的串的模式匹配算法是怎么进行比较的<br /><br />主串 (S) a b a b c a b c a c b a b<br />子串 (T

fengyu0556的专栏 426

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

KMP讲解

两种方法实现KMP算法(必懂KMP) 六之再续:KMP算法之总结篇(必懂KMP) 作者:July。 出处:http://blog.youkuaiyun.com/v_JULY_v/。转载牛人的博客。 引记     此前一天,一位MS的朋友邀我一起去与他讨论快速排序,红黑树,字典树,B树、后缀树,包括KMP算法,唯独在讲解KMP算法

JamesLi6的博客 630

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

一个比较通俗的KMP算法讲解(转)

 最近在学字符串匹配的时候接触了这个算法,算法书上都是我讨厌的下标,转来转去,头晕啊。只好上网搜一下,大部分跟书上一样,好不容易找到一篇,总算看得有些懂了。      其实最简单的字符串匹配,就是逐个逐个比较,但是这样的效率很低,而KMP算法利用了......(不说了,表达能力差啊,^_^,看看牛人怎么解释的吧)。      我们这里说的KMP不是拿来放电影的(虽然我很喜欢这个软件),而是一种算法

shockwave926的专栏 809

KMP算法基础详解

KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。 例如下面的主串与子串 ...

viafcccy的博客 487

算法领域的十位超级牛人

算法领域的十位超级牛人 1.Don E. Knuth     伟大的智者——Don E.Knuth,中文名:高德纳(1938-)算法和程序设计技术的先驱者。Oh,God!一些国外网站这样评价他。一般说来,不知道此人的程序员是不可原谅的。其经典著作《计算机程序设计艺术》更是被誉为算法中“真正”的圣经,像KMP和LR(K)这样令人不可思议的算法,在此书比比皆是。难怪连Bill Gates都说:“

渔樵阿飞 3564

解析KMP算法

字符串匹配的算法当属KMP最为著名了,人人皆知,但是KMP算法是如何做到高效率字符串匹配的呢?     我们首先来看看一般的暴力的字符串匹配算法,对于串s和模式串pattern,依次枚举s中的每一个字符作为起点与pattern尝试进行匹配,直到遇到不匹配的字符的时候,取下一个s中的字符作为起点与模式串pattern重新进行匹配。我们知道这样的时间复杂度是O(n*m)的,显然效率很不好。

Bright 1834

kmp算法next计算方法_10张图:把KMP算法按得死死的~

「字符串匹配」是计算机基本任务之一,举个栗子,有一个字符串“「aaaaaaca」",我想知道里面是否包含另一个字符串“「aaaac」”,该怎么办?这里就会使用到「串的模式匹配算法」,最常见的分别是传统的「Brute-Force(暴力)算法」和「KMP算法」。BF算法设计思想1、主串和模式串逐个字符进行比较2、当出现「字符串不相同」时,也就是「失配」时,主串的比较位置重置为起始位置的下一个...

weixin_39991055的博客 298

两种方法实现KMP算法(必懂KMP)

六之再续:KMP算法之总结篇(必懂KMP) 作者:July。出处:http://blog.youkuaiyun.com/v_JULY_v/。 转自牛人的文章,第一种方法不够直观,很难理解。第二种自我覆盖程度求Next,非常简单明了,学习KMP非常好的教程。留着以后经常回顾。 引记     此前一天,一位MS的朋友邀我一起去与他讨论快速排序,红黑树...

weixin_33795093的博客 141

KMP字符串搜索

  KMP 号称是效率最高的字符串搜索算法,大学数据结构的时候老师说这玩意不考,然后我就 直接趴下睡觉了-_-||| 。这阵子正好要做点字符串搜索的东西,顺便抄起数据结构的书看看。KMP 算法是Knuth 、Morris 、Pratt 仨牛人发 明的,不过俺也只听说过Knuth 。算法的思想不难,不过还是有点小绕脑子的。 Java SDK 的String 类中的inde...

zhugegod的专栏 144

c语言主范式与编码,超详细!终于搞明白KMP算法

小伙伴们好久不见,今天将开设“数据结构与算法”专栏,一起梳理一遍硬核课程的重要知识点,那我们开始吧正文「字符串匹配」是计算机的基本任务之一,举个栗子,有一个字符串“「aaaaaaca」",我想知道里面是否包含另一个字符串“「aaaac」”,该怎么办?这里就会使用到「串的模式匹配算法」,最常见的分别是传统的「Brute-Force(暴力)算法」和「KMP算法」。BF算法设计思想1、主串和模式串逐个字...

weixin_29495679的博客 314

模式匹配算法-KMP算法

朴素模式匹配算法的最大问题就是太低效了。于是三位前辈发表了一种KMP算法,其中三个字母分别是这三个人名的首字母大写。 简单的说,KMP算法的对于主串的当前位置不回溯。也就是说,如果主串某次比较时,当前下标为i,i之前的字符和子串对应的字符匹配,那么不要再像朴素算法那样将主串的下标回溯,比如主串为“abcababcabcabcabcabc”,子串为“abcabx”.第一次匹配的时候,主串1,2,3

但行好事,莫问前程 1212

java模式匹配算法_java 中模式匹配算法-KMP算法实例详解

java 中模式匹配算法-KMP算法实例详解朴素模式匹配算法的最大问题就是太低效了。于是三位前辈发表了一种KMP算法,其中三个字母分别是这三个人名的首字母大写。简单的说,KMP算法的对于主串的当前位置不回溯。也就是说,如果主串某次比较时,当前下标为i,i之前的字符和子串对应的字符匹配,那么不要再像朴素算法那样将主串的下标回溯,比如主串为“abcababcabcabcabcabc”,子串为“abca...

weixin_28797889的博客 417

算法届的十位牛人

·Don E. Knuth伟大的智者——Don E.Knuth,中文名:高德纳(1938-)算法和程序设计技术的先驱者。Oh,God!一些国外网站这样评价他。一般说来,不知道此人的程序员是不可原谅的。其经典著作《计算机程序设计艺术》更是被誉为算法中“真正”的圣经,像KMP和LR(K)这样令人不可思议的算法,在此书比比皆是。难怪连Bill Gates都说:“如果能做对书里所有的习题,就直接来微软上班...

weixin_34220963的博客 701
上一篇: (优化的有限背包) poj 1742 Coins
下一篇: (消一个负圈) poj 2175 Evacuation Plan
Hashmat
博客等级 码龄16年 14粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值