数据结构-4.6.KMP算法(旧版下)-朴素模式匹配算法的优化

news2024/10/9 9:23:08

一.绪论:

当主串字符和模式串字符不匹配时会执行j=next[j]来改变模式串的指针,但主串的指针不变。


二.求模式串的next数组:

1.例一:

如模式串abcabd,当第六个字符d匹配失败时,此时主串中前五个字符abcab都与模式串匹配成功,因此需要后移模式串:

模式串后移一个位置,显然主串中第二个字符b与模式串中第一个字符a不匹配,继续后移:

模式串再后移一个位置,显然主串中第三个字符c与模式串中第一个字符a不匹配,继续后移:

模式串再再后移一个位置,显然主串中第四个字符a与模式串中第一个字符a匹配,无需后移:

因此当模式串指针指向的第六个字符匹配失败时要让模式串指针从6回溯到3即next[6]为3:

2.例二:

如模式串abababcdef,当在第七个字符c匹配失败时,此时模式串中的前六个字符都能与主串匹配成功,最终需要模式串向右移动:

模式串后移一个位置,显然主串第二个字符b与模式串第一个字符a匹配失败,因此继续后移模式串:

模式串再后移一个位置,此时主串第三个字符a与模式串第一个字符a匹配成功,此时模式串无需后移:

因此当模式串指针指向的第七个字符匹配失败时要让模式串指针从7回溯到5即next[7]为5。
如果把模式串继续后移两个位置,此时模式串指针指向模式串的第三个字符a,而且模式串的第一个字符a和第二个字符b都可以匹配成功:

假设主串中字符如下图所示,此时主串指针i指向的字符和模式串第七个字符c不匹配,而且继续往后匹配,主串的c和模式串的第五个字符a匹配失败,如果按照刚才的next[7]为5,配对如下:

因此结论如下:如果有更长的一段能够匹配的上的话,优先考虑更长的这种情况

3.例三:

如模式串为aaaabcd,在第五个字符b和主串匹配失败,可知前四个字符aaaa都可以与主串匹配成功,此时需要把模式串后移:

模式串后移一个位置后,模式串前三个字符aaa都可以与主串匹配成功,此时应该让模式串里的指针回溯到4,判断是否能与主串匹配成功即next[5]为4:

显然,如果模式串再往后移一个位置,模式串和主串开头也能够匹配上,但一定能匹配成功的字符只有模式串中的前两个字符aa,主串中第五个字符还不确定是否为a,不往后移之前一定能匹配成功的字符有三个aaa,因此暂时不移动模式串较好;

4.例四:

如模式串为abcdefg,在第五个字符e时和主串匹配失败,因此模式串前4个字符abcd可以匹配成功,因此模式串需要后移:

模式串后移一个位置后,显然模式串第一个字符a与主串第二个字符b就不匹配,因此继续后移:

模式串后移一个位置后,显然模式串第一个字符a与主串第三个字符c就不匹配,因此继续后移:

模式串后移一个位置后,显然模式串第一个字符a与主串第四个字符d就不匹配,因此继续后移:

模式串后移一个位置后,此时模式串第一个字符a可能与主串第五个字符匹配成功,因此需要模式串指针从5回溯到1即next[5]为1,这个例子的特殊之处在于前几个例子中总是能找到主串已经确定的一些字符和模式串开始的字符能够匹配成功,但这个例子中主串中确定的字符中,无论后移几次模式串,都无法与主串匹配成功,所以之后需要判断主串中未知的字符能否与模式串中的字符匹配成功:

5.例五:

如模式串为abcabd,当检查到模式串中第一个字符a就发现与主串第一个字符匹配失败,此时模式串无需移动,需要检查主串的第二个字符能否与模式串中第一个字符a匹配成功:

如下图所示,此时可以先把模式串里的指针设为0:

然后主串指针和模式串指针同时加一,最终next[1]为0:

6.代码:

7.总结:

a.对于串的前缀,如模式串中第一个字符到第六个字符ababab,以ab为一段,第一个字符到第四个字符abab就是ababab的一个前缀,不包含最后一段;

b.对于串的后缀,如主串中的第一个字符到第六个字符ababab,以ab为一段,第三个字符到第六个字符abab就是ababab的一个后缀,不包含第一段;

c.注:前缀和后缀中前缀和后缀不一定只有一个字符组成,如ababab中a,ab,aba等都可以是它的前缀,后缀同理;

d.对于next[j]=S的长度等于前/后缀对的上的最大长度加一,如模式串中的S串(ababab),前缀最大就是abab,长度为4,所以S的最大长度为4+1等于5;

再比如上述图中右边的例子:模式串指针j在第五个字符时匹配失败,那么此时就要看前面的j-1个字符,由这些字符组成的字符串S(S为abcd),此时要找主串的后缀和模式串的前缀对的上的串的最大长度,先主串中从abcd后面开始取后缀d,再在模式串从abcd前面开始取前缀a,发现对不上,之后,主串中从abcd后面开始取后缀cd,模式串从abcd前面开始取前缀ab,发现还是对不上,之后,主串中从abcd后面开始取后缀bcd,模式串从abcd前面开始取前缀abc,发现还是对不上,现在主串和模式串就都不能再取了,因为主串取后缀,取后缀不能包含第一个字符,主串一共4个字符,从后面已经取了3个字符,第一个字符不能再取,模式串取前缀,取前缀不能包含最后一个字符,模式串一共4个字符,从前面已经取了3个字符,最后一个字符不能再取,所以S串最大长度为0,加一为1,因此next[5]为1:

比较特殊的情况,就是例五:


二.练习:求模式串的next数组

1.题目一:

思路:首先可以确定j为1时有next[j]为0;(其实next[1]必定为0,next[2]必定为1)

如果当 j为2即模式串指针指向的模式串第二个字符b时发现匹配失败,按照规则,第二个字符之前即第一个字符a组成的串S(只有一个a,a是第一个字符,也是最后一个字符),显然S串的前缀是空串(长度为0),因为前缀不包含最后一个字符,后缀也是一个空串(长度为0),因为主串中只有a与 模式串匹配成功,后缀不包含第一个字符,所以S串最大长度为0,加一为1,因此next[2]为1;

如果当j为3即模式串指针指向的模式串第三个字符a时发现匹配失败,说明第三个字符之前即ab都与主串匹配成功即串S为ab,串S的一个字符记为ab,显然串S没有前缀和后缀(串S取一个字符时S串最大长度也为0,当S串前缀为a时,就不能要b,对应的主串后缀就是b,就不能要a,显然前缀和后缀匹配失败,S串最大长度也为0),所以S串最大长度为0,加一为1,因此next[3]为1;

如果当j为4即模式串指针指向的模式串第四个字符b时发现匹配失败,说明第四个字符之前即aba都与主串匹配成功即串S为aba,此时前缀取一个字符a,后缀取一个字符a,只剩下b,所以S串最大长度为1,加一为2,因此next[4]为2;(其实前缀可以依次是a,ab,对应的后缀依次是a,ba,将前缀和后缀分别看成两个集合,这两个集合的交集只有一个a,所以S串最大长度为1,前缀和后缀也可以取aba,此时没有前缀和后缀,但这样的话S串最大长度为0,加一为1,因此next[4]为1,显然比next[4]为2低效,不可取,其他取前缀和后缀的原理同理,而且取前/后缀要考虑匹配最多的取);

如果当j为5即模式串指针指向的模式串第五个字符a时发现匹配失败,说明第五个字符之前即abab都与主串匹配成功即串S为abab,取前缀为ab,后缀也取ab(此时主串中有abab),显然前缀和后缀匹配成功,模式串中取了ab,长度为2,因此S串最大长度为2,加一为3,因此next[5]为3;

如果当j为6即模式串指针指向的模式串第六个字符a时发现匹配失败,说明第六个字符之前即ababa都与主串匹配成功即串S为ababa,如果前缀取aba,后缀也取aba(此时主串中有ababa,取的是第一个字符到第三个字符的aba,因为可以与模式串匹配上的字符多,不是第三个字符到第五个字符的aba),前缀和后缀可以匹配成功,模式串中取了aba,长度为3,因此S串最大长度为3,加一为4,因此next[6]为4;

2.题目二:

思路:首先可以确定j为1时有next[j]为0;可以确定j为2时有next[j]为1;

如果当j为3即模式串指针指向的模式串第三个字符a时发现匹配失败,说明第三个字符之前即aa都与主串匹配成功即串S为aa,显然前/后缀能匹配的上的最长的长度为1(取a,如果取aa的话就没有前缀和后缀了,此时前缀和后缀的长度为0),因此S串最大长度为1,加一为2,因此next[3]为2;

如果当j为4即模式串指针指向的模式串第四个字符a时发现匹配失败,说明第四个字符之前即aaa都与主串匹配成功即串S为aaa,显然前/后缀能匹配的上的最长的长度为2(取aa,如果取aaa的话前/后缀的长度为0,取a的话主串与模式串能匹配的字符最少,只有一个,不可取),因此S串最大长度为2,加一为3,因此next[4]为3;

如果当j为5即模式串指针指向的模式串第五个字符b时发现匹配失败,说明第五个字符之前即aaaa都与主串匹配成功即串S为aaaa,显然前/后缀能匹配的上的最长的长度为3(取aaa,前缀和后缀都能匹配上),因此S串最大长度为3,加一为4,因此next[5]为4。


三.求模式串的next数组的代码:

1.演示:

a.第二条求next[j]的语句中:等号左边的是模式串里的字符(即前缀),注意下标k-1,等号右边的是主串里的字符(即后缀),注意下标j-1,他们之间能够匹配的上的(相等)最大长度;k为模式串的指针,j为主串的指针;注意最长相等前后缀长度加一

b.第三条求next[j]的语句中:其他情况一般指前缀和后缀匹配失败时;

2.代码:

时间复杂度分析:从Index_KMP函数(Index_KMP函数中i为主串指针,i初始值为1,j为模式串指针,j初始值为1)开始,之后到get_next函数,然后到get_next函数里的while循环,其中i初始值为1,j初始值为0,T就是模式串,T.length就是模式串的长度,get_next函数里的while循环要循环1到T.length-1次,设T.length-1为m,那么get_next函数的while循环的时间复杂度为O(m),所以get_next函数的时间复杂度为O(m),执行完get_next函数,到了Index_KMP函数里的while循环,不需要考虑j,因为j是模式串的指针,主串的长度一般远大于模式串的长度,因此i的变化远大于j的变化,所以j就可以忽略不计了,主串指针i永远不回溯,最多不会超过主串的最后一个位置,所以while循环执行1到S.length次(S代表主串,S.length代表主串的长度),设主串的长度为n,那么Index_KMP函数里的while循环的时间复杂度为O(n),所以Index_KMP函数的时间复杂度为O(n),由此可得,Index_KMP函数的平均时间复杂度为O( (n+m)/2 ),等价于O(n+m)。


四.总结:

1.KMP算法让主串指针不回溯,只让模式串指针回溯;

2.朴素算法是主串指针和模式串指针都需要回溯;


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2198644.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Golang | Leetcode Golang题解之第462题最小操作次数使数组元素相等II

题目&#xff1a; 题解&#xff1a; func partition(a []int, l, r int) int {x : a[r]i : l - 1for j : l; j < r; j {if a[j] < x {ia[i], a[j] a[j], a[i]}}a[i1], a[r] a[r], a[i1]return i 1 }func randomPartition(a []int, l, r int) int {i : rand.Intn(r-l1…

【学习笔记】零基础入门汇编语言(ARM架构+汇编的实际应用)

目录 一.汇编的前世今生 二.寄存器 三.ARM指令集 1.指令格式 2.寻址方式 3.伪指令 4.基本指令 4.1数据传输指令 4.2存储器访问指令 4.3压栈和出栈指令 4.4跳转指令 4.5算术运算指令 4.6逻辑运算指令 四.C语言与汇编混合编程 1.混合编程前置条件 2.混合编程优势 3.…

五款专业三维数据处理工具:GISBox、Cesiumlab、OSGBLab、灵易智模、倾斜伴侣深度解析

随着三维数据处理技术的广泛应用&#xff0c;尤其是在城市规划、地理信息系统&#xff08;GIS&#xff09;、工程监测等领域&#xff0c;处理倾斜摄影、三维建模以及大规模数据管理的需求日益增加。以下是五款我精心挑选的倾斜摄影和三维数据处理工具——GISBox、Cesiumlab、OS…

和鲸科技创始人范向伟:拐点即将来临,AI产业当前的三个瓶颈

在科技迅猛发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;无疑已经成为引领新一轮产业革命的核心动力之一。全球企业纷纷拥抱AI技术&#xff0c;试图借助其变革力量在竞争中突围&#xff0c;然而业界对AI产业化的拐点何时来临却众说纷纭。毕竟AI技术从实验室到商业…

三 星 SCX-4521F 硒 鼓 清 零 及 一 般 故 障 维 修 浅 谈

基本参数 耗材容量:SCX-4521D3/XIL(3000页) 功 率:平均功率350W、休眠模式10W 一般故障讲解 一、三星SCX-4521F打印机更换硒鼓(或加粉)后仍显示墨粉用尽 (加粉清零、关闭碳粉通知) 按菜单------#1934(快速按完)------屏幕会有TECH字母显示------菜单------向…

PCB缺陷检测数据集 xml 可转yolo格式 ,共10688张图片

PCB缺陷检测数据集&#xff08;yolov5,v7,v8&#xff09; 数据集总共有两个文件夹&#xff0c;一个是pcb整体标注&#xff0c;一个是pcb部分截图。 整体标注有6个分类&#xff0c;开路&#xff0c;短路等都已经标注&#xff0c;标注格式为xml&#xff0c;每个文件夹下有100多张…

html内嵌其他网页iframe

在很多情况下&#xff0c;需要将其他网页内嵌到自己的网页&#xff0c;如&#xff1a; 只需要使用iframe标签即可&#xff0c;通过src属性指定网站地址即可&#xff0c;代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta ch…

苹果手机怎样一键删除照片:快速清理指南

在数字化时代&#xff0c;手机照片的积累如同记忆的沉淀&#xff0c;但过多无用的照片也会占据宝贵的存储空间。对于苹果手机用户来说&#xff0c;如何高效地一键删除照片是一个常见的需求。本文将介绍几种方法&#xff0c;帮助你快速清理苹果手机中的照片。 1. 使用系统相册的…

论文解析三: D2-Net 用于联合描述和检测局部特征的可训练CNN

目录 1.D2-Net摘要2.D2-Net关键点介绍3. Joint Detection and Description (联合检测和描述)3.1 Feature Extraction3.2 Feature Detection3.2.1 Hard feature detection &#xff08;硬特征检测&#xff09;3.2.1 Soft Feature Detection&#xff08;软特征检测&#xff09; 3…

如何在VScode中加入系统安装好的python环境

在vscode的ipynb文件中&#xff0c;加入的环境总是找不到自己电脑当中已有的环境。这可能是由于自己电脑中的python没有安装ipynb对应的包&#xff0c;因而监测不出来。

【自动驾驶】控制算法(十二)横纵向综合控制 | 从理论到实战全面解析

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

MP2155升降压芯片全解析——概况、性能、应用电路、输出电压调节计算

MP2155概述 功能&#xff1a; MP2155是一款高效率、低静态电流的升降压转换器&#xff0c;可在高于、低于或等于输出电压的输入电压下工作。该器件为采用单节锂离子或多节碱性电池供电的产品提供电源解决方案。 数据&#xff1a; MP2155 可在 2V 至 5.5V 的输入电压下工作&am…

<<迷雾>> 第10章 用机器做一连串的加法(2)--寄存器 示例电路

使用多个触发器可以构成一个寄存器 info::操作说明 单击按钮开关产生上升沿信号, 将 D 的输入存在 Q 端 primary::在线交互操作链接 https://cc.xiaogd.net/?startCircuitLinkhttps://book.xiaogd.net/cyjsjdmw-examples/assets/circuit/cyjsjdmw-ch10-02-register-by-multipl…

《Programming from the Ground Up》阅读笔记:p147-p180

《Programming from the Ground Up》学习第9天&#xff0c;p147-p180总结&#xff0c;总计34页。 一、技术总结 1.Physical memeory p152, Physical memory refers to the actual RAM chips inside your computer and what they contain. 物理地址指的RAM&#xff0c;即我们…

Kubernetes网络通讯模式深度解析

Kubernetes的网络模型建立在所有Pod能够直接相互通讯的假设之上&#xff0c;这构建了一个扁平且互联的网络空间。在如GCE&#xff08;Google Cloud Engine&#xff09;等云环境中&#xff0c;这一网络模型已预先配置&#xff0c;但在自建的Kubernetes集群中&#xff0c;我们需要…

深圳市步步精科技有限公司成功获得插头结构及电连接器发明专利

2024年8月20日&#xff0c;深圳市步步精科技有限公司&#xff08;以下简称“步步精”&#xff09;喜讯传来&#xff0c;公司申请的“插头结构和电连接器”专利&#xff08;授权公告号CN 118399121 B&#xff09;正式获得授权。这项创新的插头结构在数据线连接领域具有重要的应用…

[含文档+PPT+源码等]精品基于Nodejs实现的家教服务小程序的设计与实现

基于Node.js实现的家教服务小程序的设计与实现背景&#xff0c;主要源于以下几个方面&#xff1a; 一、家教市场的现状与需求 随着教育竞争的日益激烈&#xff0c;家庭对子女教育质量的重视程度不断提升&#xff0c;家教服务已成为许多家庭不可或缺的一部分。然而&#xff0c…

第三方软件测评机构简析:软件安全测试报告的内容和作用

随着数字化时代的到来&#xff0c;软件的安全性显得尤为重要。尤其在信息安全事件频发的今天&#xff0c;软件安全测试报告成为企业和开发者关注的焦点。软件安全测试报告是评估软件系统安全性的一种综合性文档&#xff0c;通常在软件开发生命周期中进行安全性测试后生成。 软…

计算机毕业设计 | SpringBoot 房屋租赁网 租房买房卖房平台(附源码)

1&#xff0c;绪论 1.1 背景调研 在房地产行业持续火热的当今环境下&#xff0c;房地产行业和互联网行业协同发展&#xff0c;互相促进融合已经成为一种趋势和潮流。本项目实现了在线房产平台的功能&#xff0c;多种技术的灵活运用使得项目具备很好的用户体验感。 这个项目的…

银河麒麟桌面操作系统中使用ufw开启防火墙

银河麒麟桌面操作系统中使用ufw开启防火墙 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 在银河麒麟桌面操作系统里&#xff0c;开启防火墙只需一个简单的步骤。 打开终端&#xff0c;然后执行命令&#xff1a; sudo ufw enable这样就能…