【数据结构与算法】KMP算法

news2024/9/28 5:33:22

文章目录

  • 前言
  • 一 .KMP的来历
  • 二.KMP解决的问题
    • 1.引入
    • 2.定义的引入
      • 1.字符串前缀
      • 2.字符串后缀
      • 3.最长相等前后缀
    • 3.核心思想
  • 三.next/prefix
    • 1.next的含义
      • 定义
      • 规律
    • 2.next的求取
      • 1.准备工作
      • 2.思路和图解
    • 4.应用

前言

 在C语言的strcmp的实现过程中,所涉及的算法较为简单,或者说只是一个简单的思路而已,在字符串过长时,所涉及的算法复杂度过大,那有没有比较简单的算法呢?这里就涉及到了KMP——由三位大佬提出的,下面我们一起来了解吧!

一 .KMP的来历

 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。
巨佬1:D.E.Knuth
巨佬2:J.H.Morris
巨佬3:V.R.Pratt
图片:
在这里插入图片描述
简介:
 沃恩·普拉特(Vaughan Pratt) (出生于1944年4月12日)是 名誉教授 在 斯坦福大学 ,他是 计算机科学 。自1969年以来,普拉特(Pratt)对基础领域做出了一些贡献,例如 搜索算法, 排序算法 , 和 素性测试 。最近,他的研究重点是对 并发系统 和 楚空间.百科全书 site:ewikizh.top

我浅浅地膜拜一下,因为从0到1创造出一个算法,那真是太牛了!
说明:在看这篇文章之前我推荐先看一下B站的视频(选择适合你的!):
1.最浅显易懂的 KMP 算法讲解
2.KMP算法易懂版
3.有两个部分
第一:帮你把KMP算法学个通透!(理论篇)
第二:帮你把KMP算法学个通透!(求next数组代码篇)
在此基础上看这篇文章,可能收获会更大!

二.KMP解决的问题

1.引入

在这里插入图片描述
 由于暴力求解(l两层for循环)的算法时间复杂度为:o(mn),我们大概看一下下面的图表:
在这里插入图片描述
将m
n最大化可以看成n^2,可知:字符串越长,求出结果所需时间也就越大,有更好的办法吗?sure!巨佬们,创造出了KMP算法,解决了这个问题。

2.定义的引入

1.字符串前缀

简单理解:
1.从开头字母到倒数第二个字母
2.开头字母依次接上第一个字母,第二字母……到倒数第二个字母,就像火车一样。
例:abc
前缀:a,ab

2.字符串后缀

简单理解:
1.从倒数第一个字母到正数第二个字母
2.从倒数第一个字母开始,依次接上倒数第二个字母,倒数第三个字母……正数第二个字母,这里字母要倒着接。
例:abc
后缀:c, bc
说明:a这是首字母也是末字母,不是前缀,也不是后缀。

3.最长相等前后缀

例1:aba
前缀:a,ab
后缀:a, ba
最长相等前后缀:a,最长相等前后缀长度是1
例2:aaaa
前缀:a,aa, aaa
后缀:a , aa, aaa
最长相等前后缀:aaa,最长相等前后缀长度是3
例3:a
前缀:无
后缀:无
最长相等前后缀:无,最长相等前后缀长度是0

3.核心思想

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

说明:我采用的是代码转换的思想,以及数学的换元法进行辅助理解。

三.next/prefix

1.next的含义

定义

 next是数组存放的是当发生比匹配的情况时:要进行的下一步操作,往往是当模式串的字符与对应的主串字符不匹配时,对应的下一步,不匹配的前一个字符跳到next下标对应的值或相似的运算。
 简单来说就是,下一步的该咋办,要写入next数组.

规律

一般是模式串下标和最长前缀后缀字符串的长度。
执行时间:当模式串的字符与主串字符串的对应字符不同时执行。
举例:
在这里插入图片描述

注意:
这里就充分利用了上一次比较的结果,使用上次比较的结果,进行下一步的比较。这里就方便了许多.
为什么方便呢?
**换元思想就是最大前缀后缀的核心,**也就是方便的原因,这里求出的最大前缀后缀长度,刚好与下标的计算差1,也就是跳去的下标,刚好与主串的前一次不一样的字符对应,可以接着比较。这里就比较凑巧。

2.next的求取

说明:
人脑计算和机器计算不一样,人脑是把字符串依次拿出来比较,计算机可做不到这样,只能将下一步可能的操作全部记录下来,也就是next数组。
那如何进行快速计算呢?
这里的主要思想:回溯思想
说明:回溯思想,就跟游击战的意思差不多,打的过就打,打不过就走。

1.准备工作

图解:
在这里插入图片描述
框架:

void get_next(char arr1[], int next[], int len)
{
	next[0] = 0;//第一个字符为0,不管字符串的长度多大。
	int i = 0;//最开始的下标
	int j = 1;//最开始的字符串大于1的模式串的下标
	for (j = 1; j > len; j++)
	{
		while (arr1[i]!=arr1[j]&&i>0)
		{
			i = arr1[i - 1];
		}
		if (arr1[i] == arr1[j])
		{
			i++;
		}
		next[j] = i;
	}
}

2.思路和图解

在这里插入图片描述

4.应用

1.字符串中找模式串,以及类似的问题。(strstr这个函数就是找模式串的函数)
说明:可能还有其它的目前我还没接触到(知识浅薄),等碰到了再进行总结。

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

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

相关文章

Golang - 字符串操作汇总

Golang 字符串操作汇总1 string初始化2 遍历string3 byte & Rune3.1 初始化3.2 byte和rune区别1 string初始化 func newString() {//1. 字符串初始化// 方式一:使用简写声明,带有字符串的变量,支持特殊字符str : "one hello \n world"fmt…

三个月后,快手To B怎么样了?

未来,如何独立作战和走出快手的TOC“客户资源圈”,或将成为快手TOB新的十字路口。 作者|斗斗 编辑|皮爷 出品|产业家 人口红利终结,流量红利终结,超常规的高速增长终结。TOC模式的路越来越难走了。 快手与抖音作为短视频…

光耦特性以及计算

光耦特性 光耦器件电路图 这是我们常用的。光耦器件以及它的连接方式。 左侧R1是我们主要考虑的。 电流最小值是要让LED能够保持发光状态,最大值的话。1.不能让LED烧坏了。2. LED的负极端是单片机的。 这里主要是看引脚灌入电流的最大值。 电气规格 我们看看说…

手机数据包抓包详解

今天继续给大家介绍渗透测试相关知识,本文主要内容是手机数据包抓包详解。 免责声明: 本文所介绍的内容仅做学习交流使用,严禁利用文中技术进行非法行为,否则造成一切严重后果自负! 再次强调:严禁对未授权设…

并发编程——6.共享模型之不可变

目录6.共享模型之不可变6.1.日期转换的问题6.1.1.问题提出6.1.2.解决思路——同步锁6.1.3.解决思路——不可变6.2.不可变设计6.3.享元模式6.3.1.简介6.3.2.体现6.3.3.DIY6.4.final 原理6.5.无状态本文笔记整理来自黑马视频https://www.bilibili.com/video/BV16J411h7Rd/?p197&…

Unity脚本(二)

视频教程:https://www.bilibili.com/video/BV12s411g7gU/?share_sourcecopy_web Transform 对象的位置、旋转和缩放 场景中的每个对象都有一个Transform,用于存储和操作对象的位置、旋转和缩放。 每个Transform都可以有一个父级,能够分…

C语言强制类型转换

强制类型转换是把变量从一种类型转换为另一种数据类型。例如,如果您想存储一个 long 类型的值到一个简单的整型中,您需要把 long 类型强制转换为 int 类型。您可以使用强制类型转换运算符来把值显式地从一种类型转换为另一种类型,如下所示&am…

gitlab-ci.yml关键字(五)tags 、only 、when

tags 使用Tags用于选择Runner的标签列表 我们在创建Runner 时可以给该Runner打上特定的标签,那后续流水线中的job如果需要使用特定标签的Runner执行时,就需要使用tags来标记 比如这里有两个标签的Runner 也可以对当前的runner进行一些配置上的设置 …

2022总结:我是怎样从一个混子到如今小有所成

前言 🍀作者简介:被吉师散养、喜欢前端、学过后端、练过CTF、玩过DOS、不喜欢java的不知名学生。 🍁个人主页:红中 🍂抽根烟,吹个牛b(不是 入门 如果硬要问我是在什么时候入门的,那就要说到高一…

MySQL添加用户及用户权限管理

目录 1、用户 <1> 用户信息 <2> 创建用户 <3> 删除用户 <4> 修改用户密码 2、用户权限管理 <1> 查看用户权限 <2> 给用户授权 <3> 回收权限 1、用户 <1> 用户信息 MySQL中的用户&#xff0c;都存储在系统数据库mysq…

机器翻译与数据集

机器翻译指的是将文本序列从一种语言自动翻译成另一种语言。 使用单词级词元化时的词表大小&#xff0c;将明显大于使用字符级词元化时的词表大小。为了缓解这一问题&#xff0c;我们可以将低频词元视为相同的未知词元。 通过截断和填充文本序列&#xff0c;可以保证所有的文…

【LeetCode每日一题】——154.寻找旋转排序数组中的最小值 II

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【题目提示】八【题目进阶】九【时间频度】十【代码实现】十一【提交结果】一【题目类别】 二分查找 二【题目难度】 困难 三【题目编号】 154.寻找旋转排序数组中的最小…

windows下OpenCV安装教程以及vs2019配置opencv教程

文章目录一. OpenCV下载二. OpenCV安装及配置三. VS2019项目配置OpenCV一. OpenCV下载 官网地址&#xff1a;Home - OpenCV 下载地址&#xff1a;OpenCV download | SourceForge.net 二. OpenCV安装及配置 双击下载好的安装包进行安装 安装过程实际上是一个解压过程 选择…

java开发机动车考试驾照考试-科一科四考试在线题库系统

简介 本系统主要是进行科一科四考试和练习的网上考试系统&#xff0c;分为A1B1、A2B2、C1C2的科一科四考试系统&#xff0c;当学员点击开始考试&#xff0c;系统将自动生成随机题目100道&#xff08;选择题80道&#xff0c;判断题20道&#xff09;的试卷&#xff0c;考试时间4…

【数据结构】LeetCode移除元素、删除排序数组中的重复项、合并两个有序数组

目录 一、移除元素 1、题目说明 2、题目解析 二、删除排序数组中的重复项 1、题目说明 2、题目解析 三、合并两个有序数组 1、题目说明 2、题目解析 一、移除元素 1、题目说明 题目链接&#xff1a;移除元素 给你一个数组nums和一个值val&#xff0c;你需要原地移除所有数值等…

php宝塔搭建部署实战彩纸屋在线少儿编程系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 本期给大家带来一套php开发的彩纸屋在线少儿编程系统源码&#xff0c;感兴趣的朋友可以自行下载学习。 技术架构 PHP7.2 nginx mysql5.7 JS CSS HTMLcnetos7以上 宝塔面板 文字搭建教程 下载源码&#x…

第一个完整的CMake工程

第一个完整的CMake工程一、概述二、准备工作2.1 创建工程2.2 创建源码目录三、换个地方保存目标二进制文件3.1 add_subdirectory 指令说明3.2 重设目标二进制生成目录四、如何安装4.1 目标文件的安装4.2 普通文件的安装4.3 非目标文件的可执行程序安装(比如脚本之类)&#xff1…

git 源码下载安装最新版本

问题 用yum install git 下载后查看版本 git --version 显示的版本太低&#xff0c;自己去github下载比较新的版本 解决 https://github.com/git/git/tags 查看最新的版本&#xff0c;并且复制tar.gz下载链接 wget 你复制的链接 我的例子&#xff1a;wget https://github.…

DevOps:开发运维全流程

目录 &#x1f9e1;什么是DevOps&#xff1f; &#x1f9e1;什么是CI/CD&#xff1f; &#x1f49f;这里是CS大白话专场&#xff0c;让枯燥的学习变得有趣&#xff01; &#x1f49f;没有对象不要怕&#xff0c;我们new一个出来&#xff0c;每天对ta说不尽情话&#xff01; &…

第一章 计算机网络体系结构

目录(1) 概念与功能(2) 组成与分类(3) 标准化工作与组织(4) 性能指标(5) 分层结构、协议、接口、服务(6) 7 层 OSI 参考模型(7) TCP/IP 模型(8) 五层参考模型(1) 概念与功能 1、概念 计算机网络&#xff1a;是一个将分散的、具有独立功能的计算机系统&#xff0c;通过通信设备…