【算法技术专题】精彩解密KMP算法之跃进式搜索的深度探索

KMP算法

  • KMP算法介绍
    • KMP算法历史
    • KMP算法思路
    • 性能损耗
    • 算法思路
      • 结构模型准备
      • KMP算法的实现步骤
        • 生成next数组
          • 构建next数组原理
            • 生成nexf数组代码实现
          • 代码案例解释说明
        • 字符串对比操作
          • 代码案例解释说明
    • 算法效果

KMP算法介绍

KMP算法(Knuth-Morris-Pratt算法)是一种字符串匹配算法,用于在一个字符串S内查找另一个字符串P的出现位置。KMP算法的核心思想是利用已经匹配过的部分信息,尽量减少不必要的字符比较,从而提高匹配效率。

KMP算法历史

KMP算法是一种字符串匹配算法,它的全称是Knuth-Morris-Pratt算法,由Donald Knuth、Vaughan Pratt和James Morris三位计算机科学家于1977年联合发明。KMP算法的核心思想是利用已知信息避免无用的字符比较,从而提高字符串匹配的效率。

KMP算法思路

KMP算法的主要思路是,对于模式串P和文本串T,我们从T的开头开始逐个字符比较,如果当前字符匹配成功,则继续比较下一个字符;如果匹配失败,则根据已知信息跳过一些比较,从而减少不必要的字符比较,提高匹配效率。

性能损耗

KMP算法解决的问题是字符匹配,这个算法把字符匹配的时间复杂度缩小到O(m+n),而空间复杂度也只有O(m),n是target的长度,m是pattern的长度。

算法思路

结构模型准备

当我们在字符串S中匹配模式串P时,KMP算法中的第一步是根据模式串P生成一个next数组。next数组的定义是,对于模式串P中的每一个位置i,next[i]表示以i为结尾的子串中,最长的既是前缀又是后缀的字符串的长度。

KMP算法的实现步骤

下面我们来具体讲解KMP算法的实现步骤。

生成next数组

例如,对于模式串P=“ababcabab”,其next数组为[0,0,1,2,0,1,2,3,4]。

构建next数组原理
  • next[0]和next[1]都为0,因为以P的第0个位置和第1个位置结尾的子串中,没有既是前缀又是后缀的字符串。

  • next[2]为1,因为以P的第2个位置结尾的子串中,"ab"既是前缀又是后缀,长度为1。以此类推,直到next[8]为4,因为以P的第8个位置结尾的子串中,"abab"既是前缀又是后缀,长度为4。

生成nexf数组代码实现

生成next数组的具体实现方法如下:

def get_next(p):"""生成next数组"""n = len(p)next = [0] * nj = 0for i in range(1, n):while j > 0 and p[i] != p[j]:j = next[j-1]if p[i] == p[j]:j += 1next[i] = jreturn next
代码案例解释说明

p为模式串,n为模式串的长度,next为生成的next数组。

我们从模式串的第1个位置开始遍历,如果当前字符与前一个字符相等,则next[i] = next[i-1] + 1;否则,我们需要找到以i-1为结尾的子串中最长的既是前缀又是后缀的字符串,这个字符串的长度就是next[i-1]。

接着,我们从这个字符串的下一个字符开始继续比较,直到找到一个字符与当前字符相等或者已经没有可比较的字符为止。如果找到了一个字符与当前字符相等,则next[i] = next[i-1] + 1;否则,next[i] = 0。

字符串对比操作

有了next数组之后,我们就可以在S中匹配P了。具体地,我们从S的开头开始逐个字符比较,如果当前字符匹配成功,则继续比较下一个字符;如果匹配失败,则根据next数组跳过一些比较。

具体来说,设当前匹配到S的第i个位置,P的第j个位置,若S[i]和P[j]不匹配,则根据next[j]的值,将j跳到next[j]位置继续匹配。这里的跳跃是利用了P中已经匹配过的部分信息,尽量减少不必要的字符比较,从而提高匹配效率。

当j跳到0位置时,表示匹配成功,返回 i-j 的值即为匹配位置在S中的起始下标。如果S中没有匹配成功的位置,则匹配失败。

具体实现代码如下:

def kmp(t, p):"""在文本串t中匹配模式串p"""n, m = len(t), len(p)next = get_next(p)j = 0for i in range(n):while j > 0 and t[i] != p[j]:j = next[j-1]if t[i] == p[j]:j += 1if j == m:return i - m + 1return -1
代码案例解释说明

t为文本串,p为模式串,n和m分别为文本串和模式串的长度,next为模式串的next数组。我们从文本串的第1个位置开始遍历,如果当前字符与模式串中对应的字符相等,则继续比较下一个字符;否则,我们根据模式串的next数组跳过一些比较。如果j跳到0位置,则表示匹配失败;如果j跳到模式串的末尾,则表示匹配成功,返回匹配位置在文本串中的起始下标。

算法效果

KMP算法的时间复杂度为O(m+n),其中m和n分别为P和S的长度。因此,KMP算法在处理长字符串匹配时具有较高的效率。

部分匹配表(Next数组):表的作用是 让算法无需多次匹配S中的任何字符。能够实现线性时间搜索的关键是 在不错过任何潜在匹配的情况下,我们"预搜索"这个模式串本身并将其译成一个包含所有可能失配的位置对应可以绕过最多无效字符的列表。

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

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

相关文章

02markdown-学习笔记

一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 换行符<br>标签 写入一段测试用的正文第二段测试文本,如果要对文本进行换行可以使用<br>标签 文本修饰符 字体为斜体的修饰&#xff0c;一对星号包含 字符为粗体&#xff0c;两对星号包含 字体为…

springboot 拦截器之Advisor不生效问题

SPringBoot使用方法注解拦截器时遇到不生效问题记录&#xff1a; 定义方法注解 Target({ElementType.TYPE, ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Inherited Documented public interface DataScope {boolean enable() default true;}定义 Advisor Getter…

出现 java: 找不到符号 符号: 变量 log 的解决方法

目录 1. 问题所示2. 原理分析3. 解决方法3.1 增加编译参数3.2 增加lombok插件3.3 清楚本地缓存1. 问题所示 使用Springboot启动项目的时候,出现如下bug: java: 找不到符号符号: 变量 log位置: 类 org.springblade.example.consumer.rpc.BlogStu

如何定位线上OOM?

文章目录 造成OOM的原因1.一次性申请的太多2. 内存资源耗尽未释放3.本身资源不够 如何快速定位OOM&#xff1f;1.系统已经OOM了2.系统运行中还未OOM2.1导出dump文件&#xff1a;2.2.结合jvisualvm进行调试2.3 利用ArthasArthas可以做什么&#xff1f;如何使用Arthas小结 造成OO…

Docker常用命令总结

文章目录 Docker命令总结 Docker命令总结 简介&#xff1a;Docker是一个基于轻量级虚拟化技术的容器&#xff0c;整个项目基于Go语言开发&#xff0c;并采用了Apache 2.0协议。Docker可以将我们的应用程序打包封装到一个容器中&#xff0c;该容器包含了应用程序的代码、运行环…

【带头学C++】----- 九、类和对象 ---- 9.13 运算符重载——(9.13.7-9.13.8)

❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️创做不易&#xff0c;麻烦点个关注❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️ ❤️❤️❤️❤️❤️❤️❤️❤️❤️文末有惊喜&#xff01;献舞一支&#xff01;❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️ 目录 9.13…

Git篇---第九篇

系列文章目录 文章目录 系列文章目录前言一、使用过git merge和git rebase吗?它们之间有什么区别?二、使用过git cherry-pick,有什么作用?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看…

GPIO模拟MDIO

背景 CPU&#xff1a;AST2500 驱动里实现GPIO模拟MDIO驱动,参考内核驱动mdio-bitbang.c和mdio-gpio.c&#xff0c;当前项目不支持设备树&#xff0c;驱动需要改成platform注册 MDIO介绍 SMI接口 SMI是MAC内核访问PHY寄存器接口&#xff0c;它由两根线组成&#xff0c;双工…

旅游规划

有了一张自驾旅游路线图&#xff0c;你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序&#xff0c;帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的&#xff0c;那么需要输出最便宜的一条路径。 输入格式: …

c++ qt 窗口开发中 俩按钮组合 配合 显影 已解决

在日常项目中&#xff0c;有这么需求&#xff0c;还想窗口移动&#xff0c;还想 右侧关闭 还能tab栏点击显影的需求&#xff0c;不得使用 qt模拟点击事件 进行功能优化 特大杯 大杯 控制 窗口显影&#xff0c; 咖啡 按钮 显示窗口 可乐 豆浆 不显示窗口 四个按钮的 互斥关…

Amazon SageMaker机器学习之旅的助推器

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 一、前言 在当今的数字化时代&#xff0c;人工智能和机器学习已经…

Android Studio报Gradle问题解决思路

Gradle的版本号与Android studio版本、AGP&#xff08;Android Gradle Plugin&#xff09;版本、jdk版本都有关系。只有同时匹配三个版本号&#xff0c;才能使用对应的Gradle版本。 1、AGP的版本号与Android studio版本的关系。 Google 搜索 Android studio gradle plugin re…

2023一起益企广东省中小企业数字化赋能活动(深圳站)成功举办

12月12日&#xff0c;由广东工业和信息化厅指导&#xff0c;广东省中小企业服务中心、深圳市中小企业服务局主办&#xff0c;深圳联通承办的2023年“一起益企”广东省中小企业数字化赋能专项对接志愿服务活动&#xff08;深圳站&#xff09;在深圳成功举办。 本次活动涵盖中小企…

【AI底层逻辑】——“数学华尔兹”之一元线性回归

一元线性回归模型想必大家都耳熟能详&#xff0c;这里不再赘述。但在使用python中机器学习包时一定见过类似模型评价参数的输出&#xff0c;这一章我们就讲一讲回归分析里一些模型评价概念&#xff01; 一、方差分析ANOVA 方差分析是一种用于确定线性回归模型中不同变量对目标…

【改进YOLOv8】车辆测距预警系统:融合空间和通道重建卷积SCConv改进YOLOv8

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义&#xff1a; 随着交通工具的普及和道路交通的不断增加&#xff0c;车辆安全问题日益凸显。特别是在高速公路等高速道路上&#xff0c;车辆之间的距离和速度差异较…

1036 跟奥巴马一起编程

美国总统奥巴马不仅呼吁所有人都学习编程&#xff0c;甚至以身作则编写代码&#xff0c;成为美国历史上首位编写计算机代码的总统。2014 年底&#xff0c;为庆祝“计算机科学教育周”正式启动&#xff0c;奥巴马编写了很简单的计算机代码&#xff1a;在屏幕上画一个正方形。现在…

【论文】 虚拟机 和 Linux容器 的 最新性能比较

虚拟机 和 Linux容器 的 最新性能比较 An Updated Performance Comparison of Virtual Machines and Linux Containers 借助DeepL辅助翻译 校准 摘要 云计算广泛使用虚拟机&#xff08;VM&#xff09;&#xff0c;因为它们允许工作负载相互隔离&#xff0c;并在一定程度上控…

springboot框架的客制化键盘个性化商城网站

客制化键盘网站是从客制化键盘的各部分统计和分析&#xff0c;在过程中会产生大量的、各种各样的数据。本文以客制化键盘管理为目标&#xff0c;采用B/S模式&#xff0c;以Java为开发语言&#xff0c;Jsp为开发技术、idea Eclipse为开发工具&#xff0c;MySQL为数据管理平台&am…

西南科技大学数字电子技术实验七(4行串行累加器设计及FPGA实现)FPGA部分

一、实验目的 1、掌握基于Verilog语言的diamond工具设计全流程。 2、熟悉、应用Verilog HDL描述数字电路。 3、掌握Verilog HDL的组合和时序逻辑电路的设计方法。 4、掌握“小脚丫”开发板的使用方法。 二、实验原理 三、程序清单&#xff08;每条语句必须包括注释或在开发…

Leetcode 491 递增子序列

题意理解&#xff1a; 输入&#xff1a;nums [4,6,7,7] 输出&#xff1a;[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]] 这里不止要找一个子序列&#xff0c;还要元素保证其在原来的集合中的前后顺序&#xff0c;且应为增序。 为保证一个增序序列&#xff0c;…