KMP 算法(Knuth–Morris–Pratt algorithm)的基本思想

2024-03-22 11:10

本文主要是介绍KMP 算法(Knuth–Morris–Pratt algorithm)的基本思想,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

KMP 算法(Knuth–Morris–Pratt algorithm)的基本思想

阅读本文之前,您最好能够了解 KMP 算法解决的是什么问题,最好能用暴力方式(Brute Force)解决一下该问题。
KMP 算法主要想解决的是文本搜索的问题: 给定一个模式字符串 p 和一个子串 t, 找出 p 串出现在 t 串中的位置。

术语定义


  • "abc"(引号中的字符串): 代表字符串字面值
  • a…z(单个斜体小写字母): 代表字符串。
  • A…Z(单个大写字母):代表单个字符。
  • prefix(x, n): 字符串 x 的前 n 个字符构成的子串(前缀)。
  • suffix(x, n): 字符串 x 的后 n 个字符构成的子串(后缀)。
  • |a|: 字符串 a 的长度。

如: 字符串 x = "abcdef", 则 prefix( x, 3) = "abc", suffix( x, 3) = "def",| x| = 6。

KMP 算法的基本思想

假设字符串 x = prefix(p, n),且存在 i > 0 使得字符串 y := prefix(x, i) := suffix(x, i),
p, xy 之间的关系如下图:

p,x,y之间的关系

t 串匹配到 p 串的前缀x,并且在 x 串的下一个串匹配失败,如下图:

匹配失败

仔细观察上图可以发现,此次匹配失败后,我们不用按照暴力算法直接将 p 串移动一位,从头开始比较。
而是将 prefix(x, i) 移动到 suffix(x, i) 的位置,继续比较第 |y|+1 位。
这是因为此时已经匹配成功的 p 串和 x 串(即, prefix(t,n)) 相等。
结合下图(移动后的情况),仔细理解上一句话:

下一次匹配的情况

以上,就是 KMP 算法的最核心思想。我们不难发现,i 越大,移动之后匹配成功的字符就越多, 并且只有 i 取得最大值时, 才不会移动过多的位。
因此,KMP 算法找的是使得 prefix(p, i) == suffix(p, i) 最大的 i, 记作 i_max, 此时的 y 串记作 y _max。

容易求得,每次移动的位数是 |x| - | y _max|。
将 prefix(p, 1…|p|) (即 p 串的所有前缀 ) 的 i_max 打成一个表格,就是 KMP 算法所谓的 next 数组。

这篇关于KMP 算法(Knuth–Morris–Pratt algorithm)的基本思想的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/yanglingwell/article/details/79829549
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/835179

相关文章

Python Faker库基本用法详解

《PythonFaker库基本用法详解》Faker是一个非常强大的库,适用于生成各种类型的伪随机数据,可以帮助开发者在测试、数据生成、或其他需要随机数据的场景中提高效率,本文给大家介绍PythonF... 目录安装基本用法主要功能示例代码语言和地区生成多条假数据自定义字段小结Faker 是一个 python

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

SpringBoot整合MybatisPlus的基本应用指南

《SpringBoot整合MybatisPlus的基本应用指南》MyBatis-Plus,简称MP,是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,下面小编就来和大家介绍一下... 目录一、MyBATisPlus简介二、SpringBoot整合MybatisPlus1、创建数据库和

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

Python中多线程和多进程的基本用法详解

《Python中多线程和多进程的基本用法详解》这篇文章介绍了Python中多线程和多进程的相关知识,包括并发编程的优势,多线程和多进程的概念、适用场景、示例代码,线程池和进程池的使用,以及如何选择合适... 目录引言一、并发编程的主要优势二、python的多线程(Threading)1. 什么是多线程?2.

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1