数据结构面试常见问题之串的模式匹配(KMP算法)系列-大师改进

本文主要是介绍数据结构面试常见问题之串的模式匹配(KMP算法)系列-大师改进,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

😀前言
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)

KMP算法的优势:

提高了匹配效率,时间复杂度为O(m+n),其中m为模式串长度,n为主串长度。
克服了朴素算法的回溯问题,减少了不必要的比较次数。

🏠个人主页:尘觉主页

文章目录

  • 数据结构面试常见问题之串的模式匹配(KMP算法)系列-大师改进
    • KMP-2. KMP 算法思路
      • 大师改进
      • 模式匹配类型
    • 😄总结
      • KMP算法思路
      • next数组的含义:
      • 大师改进:KMP算法
      • 改进后的next数组计算方法:
      • 总结

数据结构面试常见问题之串的模式匹配(KMP算法)系列-大师改进

KMP-2. KMP 算法思路

大师改进

方法3:KMP(Knuth、Morris、Pratt)算法

T = O(n+m)
简单的往前错一位的比较是完全没有必要的没有意义的,如下图
在这里插入图片描述
KMP算法的想法:
在这里插入图片描述
指针指向x不会回退(回溯)了,直接继续从x开始,继续往前比较
在这里插入图片描述
match的具体例子
在这里插入图片描述

下标从090个字符对应的是一个长度为1的子串,所以他不可能产生匹配,match就永远是-101:a跟b是配不上的,match也为-1
0-2:a和c配不上,ab和bc也配不上,所以match还是为-1
0-3:ab和ca是配不上的,abc跟bca也配不上,a对应的j为0,所以match也为0
//此时限制条件是最大i是小于j的,如果i=j的话那就相当于自己等于自己就没有意义了(p0...pj =p0...pj)
//所以我们考虑他的真子串
0-4:a跟b配不上,abc跟cab配不上,ab跟ab能配上,match值为1...

对于 pattern = abcabcacab,最后 3 个字符的 match 值是多少?-1, 0, 1
在早期的教科书上被叫做failure(失败的意思)

match值的含义:
例子:从0到6的子串,首跟尾能配上的小串,从0开始他的尾部下标为3,abca跟abca能配上。这就是match的含义

此代码块内容来自百度百科:
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)
KMP算法是三位学者在 Brute-Force算法的基础上同时提出的模式匹配的改进算法。Brute- Force算法在模式串中有多个字符和主串中的若干个连续字符比较都相等,但最后一个字符比较不相等时,主串的比较位置需要回退。KMP算法在上述情况下,主串位置不需要回退,从而可以大大提高效率

模式匹配类型

(1)精确匹配
如果在目标T中至少一处存在模式P,则称匹配成功,否则即使目标与模式只有一个字符不同也不能称为匹配成功,即匹配失败。给定一个字符或符号组成的字符串目标对象T和一个字符串模式P,模式匹配的目的是在目标T中搜索与模式P完全相同的子串,返回T和P匹配的第一个字符串的首字母位置 。
(2)近似匹配
如果模式P与目标T(或其子串)存在某种程度的相似,则认为匹配成功。常用的衡量字符串相似度的方法是根据一个串转换成另一个串所需的基本操作数目来确定。基本操作由字符串的插入、删除和替换来组成

第一篇–>数据结构面试常见问题之串的模式匹配(KMP算法)系列-简单解决方案

第二篇–>数据结构面试常见问题之串的模式匹配(KMP算法)系列-大师改进

第三篇–>数据结构面试常见问题之串的模式匹配(KMP算法)系列-大师改进实现以及原理

😄总结

KMP算法思路

KMP算法的核心思想是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数。具体来说,KMP算法通过一个next数组记录模式串的部分匹配信息,当主串与模式串匹配失败时,可以根据next数组直接跳转到模式串中下一个可能匹配的位置,避免回溯。

next数组的含义:

next[j]表示模式串P的前j个字符(不包括第j个字符)与P的后缀中最长的公共前缀的长度。

举个例子:

模式串P = “ABCDABD”

next[0] = -1 (空串与任何字符串都没有公共前缀)

next[1] = 0 (A与空串的公共前缀是空串)

next[2] = 0 (AB与A的公共前缀是A)

next[3] = 1 (ABC与AB的公共前缀是AB)

next[4] = 2 (ABCD与ABC的公共前缀是ABC)

next[5] = 3 (ABCDAB与ABCD的公共前缀是ABCD)

next[6] = 2 (ABCDABD与ABCDAB的公共前缀是ABCDAB)

大师改进:KMP算法

KMP算法的核心改进在于next数组的计算。朴素的next数组计算方法是逐个计算每个next[j]的值,时间复杂度为O(m^2)。KMP算法通过改进next数组的计算方法,将时间复杂度降低到O(m)。

改进后的next数组计算方法:

初始化next[0] = -1
从j = 1开始循环
若P[j] = P[next[j-1]],则next[j] = next[j-1] + 1
若P[j] != P[next[j-1]],则
若next[j-1] != -1,则令j = next[j-1],并重复步骤3
若next[j-1] == -1,则next[j] = 0

总结

KMP算法是字符串匹配领域的重要算法,具有广泛的应用价值。KMP算法的核心思想是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数,从而提高匹配效率。

😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

这篇关于数据结构面试常见问题之串的模式匹配(KMP算法)系列-大师改进的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/842492

相关文章

数据库面试必备之MySQL中的乐观锁与悲观锁

《数据库面试必备之MySQL中的乐观锁与悲观锁》:本文主要介绍数据库面试必备之MySQL中乐观锁与悲观锁的相关资料,乐观锁适用于读多写少的场景,通过版本号检查避免冲突,而悲观锁适用于写多读少且对数... 目录一、引言二、乐观锁(一)原理(二)应用场景(三)示例代码三、悲观锁(一)原理(二)应用场景(三)示例

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

PyInstaller打包selenium-wire过程中常见问题和解决指南

《PyInstaller打包selenium-wire过程中常见问题和解决指南》常用的打包工具PyInstaller能将Python项目打包成单个可执行文件,但也会因为兼容性问题和路径管理而出现各种运... 目录前言1. 背景2. 可能遇到的问题概述3. PyInstaller 打包步骤及参数配置4. 依赖

springboot+dubbo实现时间轮算法

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

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

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

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

Spring Boot 整合 MyBatis 连接数据库及常见问题

《SpringBoot整合MyBatis连接数据库及常见问题》MyBatis是一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,下面详细介绍如何在SpringBoot项目中整合My... 目录一、基本配置1. 添加依赖2. 配置数据库连接二、项目结构三、核心组件实现(示例)1. 实体类2. Ma

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

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

Android WebView无法加载H5页面的常见问题和解决方法

《AndroidWebView无法加载H5页面的常见问题和解决方法》AndroidWebView是一种视图组件,使得Android应用能够显示网页内容,它基于Chromium,具备现代浏览器的许多功... 目录1. WebView 简介2. 常见问题3. 网络权限设置4. 启用 JavaScript5. D

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

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