KMP算法完整教程 (下)

article/2025/10/25 6:13:23

下面我们用数学归纳法来解决这个填值的问题。

这里我们借鉴数学归纳法的三个步骤(或者说是动态规划?):

  • 1、初始状态

  • 2、假设第j位以及第j位之前的我们都填完了

  • 3、推论第j+1位该怎么填

初始状态我们稍后再说,我们这里直接假设第j位以及第j位之前的我们都填完了。也就是说,从上图来看,我们有如下已知条件:

next[j] == k;next[k] == 绿色色块所在的索引;next[绿色色块所在的索引] == 黄色色块所在的索引;

这里要做一个说明:图上的色块大小是一样的(没骗我?好吧,请忽略色块大小,色块只是代表数组中的一位)。

我们来看下面一个图,可以得到更多的信息:
这里写图片描述

1.由”next[j] == k;”这个条件,我们可以得到A1子串 == A2子串(根据next数组的定义,前后缀那个)。

2.由”next[k] == 绿色色块所在的索引;”这个条件,我们可以得到B1子串 == B2子串。

3.由”next[绿色色块所在的索引] == 黄色色块所在的索引;”这个条件,我们可以得到C1子串 == C2子串。

4.由1和2(A1 == A2,B1 == B2)可以得到B1 == B2 == B3。

5.由2和3(B1 == B2, C1 == C2)可以得到C1 == C2 == C3。

6.B2 == B3可以得到C3 == C4 == C1 == C2

上面这个就是很简单的几何数学,仔细看看都能看懂的。我这里用相同颜色的线段表示完全相同的子数组,方便观察。

接下来,我们开始用上面得到的条件来推导如果第j+1位失配时,我们应该填写next[j+1]为多少?

next[j+1]即是找strKey从0到j这个子串的最大前后缀:

#:(#:在这里是个标记,后面会用)我们已知A1 == A2,那么A1和A2分别往后增加一个字符后是否还相等呢?我们得分情况讨论:
  • (1)如果str[k] == str[j],很明显,我们的next[j+1]就直接等于k+1。

      用代码来写就是next[++j] = ++k;

  • (2)如果str[k] != str[j],那么我们只能从已知的,除了A1,A2之外,最长的B1,B3这个前后缀来做文章了。

那么B1和B3分别往后增加一个字符后是否还相等呢?

由于next[k] == 绿色色块所在的索引,我们先让k = next[k],把k挪到绿色色块的位置,这样我们就可以递归调用”#:”标记处的逻辑了。

由于j+1位之前的next数组我们都是假设已经求出来了的,因此,上面这个递归总会结束,从而得到next[j+1]的值。

我们唯一欠缺的就是初始条件了:

next[0] = -1, k = -1, j = 0

另外有个特殊情况是k为-1时,不能继续递归了,此时next[j+1]应该等于0,即把j回退到首位。

即 next[j+1] = 0; 也可以写成next[++j] = ++k;

这里我们用Java来描述:
“`
public static int[] getNext(String ps)

{

char[] strKey = ps.toCharArray();int[] next = new int[strKey.length];// 初始条件int j = 0;int k = -1;next[0] = -1;// 根据已知的前j位推测第j+1位while (j < strKey.length - 1){if (k == -1 || strKey[j] == strKey[k]){next[++j] = ++k;}else{k = next[k];}}return next;

}

##三。KMP算法的优化和改进KMP算法是可以被进一步优化的。我们以一个例子来说明。譬如我们给的P字符串是“abcdaabcab”,经过KMP算法,应当得到“特征向量”如下表所示:
![这里写图片描述](https://img-blog.csdn.net/20180205200048696?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ2l0aHViXzM4ODg1Mjk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
但是,如果此时发现p(i) == p(k),那么应当将相应的next[i]的值更改为next[k]的值。经过优化后可以得到下面的表格:
![这里写图片描述](https://img-blog.csdn.net/20180205200107143?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ2l0aHViXzM4ODg1Mjk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
- (1next[0]= -1 意义:任何串的第一个字符的模式值规定为-1。- (2next[j]= -1 意义:模式串T中下标为j的字符,如果与首字符相同,且j的前面的1—k个字符与开头的1—k个字符不等(或者相等但T[k]==T[j])(1≤k如:T=”abCabCad” 则 next[6]=-1,因T[3]=T[6]-(3next[j]=k 意义:模式串T中下标为j的字符,如果j的前面k个字符与开头的k个字符相等,且T[j] != T[k] (1≤k即T[0]T[1]T[2]。。。T[k-1]==T[j-k]T[j-k+1]T[j-k+2]…T[j-1]且T[j] != T[k].(1≤k- (4) next[j]=0 意义:除(1)(2)(3)的其他情况。于是乎我们修正的NEXT数组的求法如下:

public static int[] getNext(String ps)

{

char[] strKey = ps.toCharArray();int[] next = new int[strKey.length];// 初始条件int j = 0;int k = -1;next[0] = -1;// 根据已知的前j位推测第j+1位while (j < strKey.length - 1){if (k == -1 || strKey[j] == strKey[k]){// 如果str[j + 1] == str[k + 1],回退后仍然失配,所以要继续回退if (str[j + 1] == str[k + 1]){next[++j] = next[++k];}else{next[++j] = ++k;}}else{k = next[k];}}return next;

}
“`
好了,以上就是KMP算法的所有内容,我们可以看出,KMP算法的关键就是:利用匹配失败后的信息,利用递归的思想为每一个字符算出一个“特征值”。最后,KMP算法适合在字符种类很稀疏的情况下适用:仅当模式与主串之间存在许多“部分匹配”的情况下才显得比“暴力匹配”快,但是如果模式串中有太多相同的字符,就会略微降低KMP的优化效果。KMP算法还有一个进步特点就是:指示主串的指针不需要回溯,对主串仅需从头至尾扫描一遍。

(如需转载请标明出处)


http://chatgpt.dhexx.cn/article/cSBCHb44.shtml

相关文章

多态以及它的单继承、多继承、菱形继承的对象模型

什么是多态 同一件事物在不同的场景下表现忽的多种形态。不同类的对象对同一消息做出响应&#xff0c;同一消息可以根据发送对象的不同而采用多种不同的行为方式。 静态多态 在编译期间&#xff0c;确定程序的行为&#xff08;确定具体调用哪个函数&#xff09; 动态多态 程…

WEBBASIC Unit01 Web概述 、 HTML概述 、 文本处理 、 图像和超链接 、 表格 、 表单

一.课程介绍 1.HTML(1.5天) 勾勒出网页的结构和内容 2.CSS(3天) 美化网页 3.JavaScript(4天) 让网页呈现动态的数据和效果 4.jQuery(1.5天) 是一个框架,提高JS的开发效率 二.WEB概述 三.XML和HTML对比 1.XML 可扩展(自定义)标记语言标记、属性、标记之间的关系都可以…

HTML5_超链接、锚点、下载、表格、表格嵌套、列表、页面布局、表单

1、修改图片的高度和宽度 ● 1、如果要修改一张图片的尺寸&#xff0c;最好先算好宽度与高度的比例 ● 2、如果修改图片时 只修改宽度或者只修改高度时另一项属性会根据宽度或者告诉的缩放比例进行调整 2、PNG图片和JPG图片 PNG格式的图片 一般保存白色背景为透明色的图片…

js 点击table的某个单元格实现对应列的单元格变色

本文用于用js来实现&#xff1a;点击table的某个单元格实现对应列的单元格变色 一、表格CSS样式 <style>* {margin: 0;padding: 0;}table {width: 800px;height: 300px;}table,tr,td {border: 1px solid;border-collapse: collapse;}</style> 二、表格结构&#xf…

表格布局(TableLayout)及重要属性

TableLayout属性&#xff1a; android:collapseColumns:将TableLayout里面指定的列隐藏&#xff0c;若有多列需要隐藏&#xff0c;请用逗号将需要隐藏的列序号隔开。 android:stretchColumns:设置指定的列为可伸展的列&#xff0c;以填满剩下的多余空白空间&#xff0c…

Layout布局之表格布局

适用于多行多列的布局格式,每个TableLayout是由多个TableRow组成,一个TableRow就表示TableLayout中的每一行,这一行可以由多个子元素组成。实际上TableLayout和TableRow都是LineLayout线性布局的子类。但是TableRow的参数android:orientation属性值固定为horizontal,且andr…

前端表格排序插件TableSort资料整理

** 前端表格排序插件TableSort资料整理 ** 一、前言 项目实际开发中&#xff0c;经常会遇到对表格排序的需求&#xff0c;下面整理了几个常用的表格排序方法。 二、 常用插件 1、jquery.tablesorter.js &#xff0c; 用法参考这篇文章&#xff1a;https://www.cnblogs.co…

Type setting_latex 表格

彩色表格 [plain] view plain copy print ? \begin{table} </span></span></li><li class""><span>\centering </span></li><li class"alt"><span>\caption{彩色的表格} </span></li&…

JSB 原理与实践

大厂技术 坚持周更 精选好文 什么是 JSB 我们开发的 h5 页面运行在端上的 WebView 容器之中&#xff0c;很多业务场景下 h5 需要依赖端上提供的信息/能力&#xff0c;这时我们需要一个可以连接原生运行环境和 JS 运行环境的桥梁 。 这个桥梁就是 JSB&#xff0c;JSB 让 Web 端…

html一个带图片的表格,Html表格

&#xfeff;&#xfeff; 在解说今天Html表单之前。还是先看张图片来刺激一下。 源代码超链接演示 仿百度搜索框 请输入要搜索的内容&#xff1a; 看了上图百度的搜索页面&#xff0c;有木有心动一下&#xff0c;别慌你也能够的。这就是我们今天要讲的表单。 什么是Html表单—…

最新百度云不限速软件

直接放图不废话。 下载链接&#xff1a;https://pan.baidu.com/s/1ZDo6xMjMW525sH7FUB6QEA提取码&#xff1a;xey9

获取百度云盘不限速下载软件 每秒达到10兆 这叫一个“爽”

公众号内回复&#xff1a;不限速 即可获取下载链接 下载资源啦 永远也不需要开通VIP 赶快去下载吧 小编亲自体验下载速度 行走在岁月的小巷&#xff0c;听风&#xff0c;读雨&#xff0c;夜色空寂&#xff0c;一切烟云&#xff0c;皆会慢慢散去&#xff0c;光阴眷顾&a…

一款百度网盘不限速下载工具

此工具收集于网络&#xff0c;如有侵权请联系删除&#xff01;&#xff01;&#xff01; 此工具仅用于个人学习&#xff0c;请勿用于商业获利&#xff0c;造成后果自负&#xff01;&#xff01;&#xff01; 这款免费的百度云高速下载工具&#xff1a; 界面美观&#xff0c;…

百度云下载不限速方法+软件

转自&#xff1a;https://www.52pojie.cn/thread-888047-1-1.html 1、Pandownload这个不用多说&#xff0c;功能强大。目前是我的主力。 2、速盘速盘用得比较少&#xff0c;大致和pandownload差不多。 3、百度云下载神器这种就我个人来说比较鸡肋&#xff0c;需要在网页版的百度…

无封号风险,2020最新百度网盘不限速下载软件,下载速度10M/S

前不久给大家带来的卢本伟大神修改的pandownload不知道大家还在没在用&#xff0c;能不能用&#xff0c; 今天小七就在给大家带来一款度盘高速下载工具&#xff0c;软件完全免费并且没有任何下载限制&#xff0c;而且相比pandownload需要登录百度账号&#xff0c;这款软件无需…

Linux下载工具photon,不限速、免配置的 Aria2 免费开源下载软件 Photon,替代迅雷的...

原标题&#xff1a;不限速、免配置的 Aria2 免费开源下载软件 Photon&#xff0c;替代迅雷的 谈到下载软件除迅雷、IDM 之外&#xff0c;想必很多人都听过 Aria2 的大名&#xff0c;它绝对是跨平台不限速的“神器级”下载工具&#xff0c;可由于它是「命令行」软件&#xff0c;…

百度云下载不限速方式集合

因为百度云限速严重&#xff0c;因此很多时候都是在寻找相应的工具去破解百度云&#xff0c;这里整理一下自己一般用的一些工具的方法。&#xff08;有些方式有些时候会被官方和谐&#xff0c;因此多试几种&#xff09; 文章目录 1、使用第三方工具pandownload2、使用油猴脚本配…

解决微云下载限速问题

1.首先将文件存到微云 2.打开手机我的设备&#xff0c;我的电脑&#xff08;也可以是好友&#xff09;&#xff0c;找到发送文件 3.点击微云&#xff0c;找到微云里面的文件&#xff0c;点击发送 4.就可以在电脑端不限速下载了 注意但是好像根据很多人的反馈4GB以上的好像发不过…

【更新】网盘不限速下载 2021.01.13

哈喽大家好嘞&#xff01; 最近一直都有好多朋友们反馈&#xff0c; 以往的百度网盘都不能用了&#xff0c; 安排&#xff0c;这就安排。 大家在学习知识的同时&#xff0c;不要忘记点赞呦&#xff01; ★ KinhDown 搜集了全网&#xff0c;可算是找到了一个能用的&#xf…

android http下载限速,安卓手机端两种让网盘不限速下载方法介绍

百度网盘已然成为分享型网盘中一家独大的“大佬”了。时代就是这样不管你喜不喜欢&#xff0c;上网总会遇到些百度网盘共享的文件需要下载。然而&#xff0c;百度网盘对免费用户的限速已经到了“感人”的地步了&#xff0c;常常十多KB/秒的速度真能让人崩溃&#xff01;虽说会员…