一文搞懂KMP算法!!!

news2024/10/5 15:27:35

一文搞懂KMP算法!!!

  • 🍁什么是KMP算法?
  • 🍁什么是 next() 数组 和 前缀表?
      • 前缀表有什么作用呢
      • 最长公共前后缀
      • 如何计算前缀表
  • 🚀 构造next数组
  • 🚀 使用next数组来做匹配

🍁什么是KMP算法?

  • KMP算法是一种改进的 字符串匹配算法,由 D.E.KnuthJ.H.MorrisV.R.Pratt 提出的,因此人们称它为 克努特—莫里斯—普拉特 操作(简称 KMP 算法)。
    • KMP 算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。
    • 具体实现就是通过一个 next() 数组实现,数组本身包含了模式串的局部匹配信息。KMP 算法的时间复杂度 O ( m + n ) O(m+n) O(m+n)

🍁什么是 next() 数组 和 前缀表?

next 数组就是一个前缀表(prefix table)!

前缀表有什么作用呢

前缀表是用来回退的,它记录了 模式串主串(文本串) 不匹配的时候,模式串 应该从哪里开始重新匹配。

我们来举一个例子:

  • 要在文本串aabaabaafa 中查找是否出现过一个模式串aabaaf

如动画所示

在这里插入图片描述

最长公共前后缀

  • 字符串的前缀是:指不包含最后一个字符的所有 以第一个字符开头的连续子串
  • 后缀:是指不包含第一个字符的所有 以最后一个字符结尾的连续子串

正确理解什么是前缀什么是后缀很重要!
可以理解为最长相等前后缀

如何计算前缀表

注意字符串的前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串;后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串。

  1. 长度为前1个字符的子串 a,最长相同前后缀的长度为 0

在这里插入图片描述

  1. 长度为前2个字符的子串 aa ,最长相同前后缀的长度为 1

在这里插入图片描述
3. 长度为前3个字符的子串 aab,最长相同前后缀的长度为 0

在这里插入图片描述

  1. 以此类推: 长度为前4个字符的子串 aaba,最长相同前后缀的长度为 1
  2. 长度为前5个字符的子串aabaa,最长相同前后缀的长度为 2
  3. 长度为前6个字符的子串aabaaf,最长相同前后缀的长度为 0

在这里插入图片描述

🚀 构造next数组

构造 next 数组其实就是计算 模式串 s

  • 定义两个指针 ijj 指向前缀末尾位置i 指向后缀末尾位置
  • next[i] 表示 i(包括 i )之前最长相等的前后缀长度(其实就是 j)。

前缀表的过程。 主要有如下三步:

  1. 初始化:
    • j 初始化为 -1;
  2. 处理前后缀不相同的情况
    • 因为 j 初始化为 -1,那么 i 就从1 开始,进行 s[i]s[j+1] 的比较;
    • 如果 s[i]s[j+1] 不相同,也就是遇到 前后缀末尾不相同的情况,就要向前回退。
      • next[j] 就是记录着 j(包括 j )之前的子串的相同前后缀的长度;
      • 那么 s[i]s[j+1] 不相同,就要找 j+1 前一个元素在 next 数组里的值(就是 next[j] )。
  3. 处理前后缀相同的情况
    • 如果 s[i]s[j + 1] 相同,那么就同时向后移动 ij 说明找到了相同的前后缀,同时还要将 j(前缀的长度)赋给 next[i] , 因为 next[i] 要记录相同前后缀的长度。

构造 next 数组的逻辑流程动画如下:
在这里插入图片描述
构造 next 数组的函数如下:(C++)

void getNext(int* next, const string& s){
    int j = -1;
    next[0] = j;
    for(int i = 1; i < s.size(); i++) { // 注意i从1开始
        while (j >= 0 && s[i] != s[j + 1]) { // 前后缀不相同了
            j = next[j]; // 向前回退
        }
        if (s[i] == s[j + 1]) { // 找到相同的前后缀
            j++;
        }
        next[i] = j; // 将j(前缀的长度)赋给next[i]
    }
}

🚀 使用next数组来做匹配

在文本串 s 里找是否出现过模式串 t

  • 定义两个下标 j 指向模式串起始位置,i 指向文本串起始位置;
  • j 初始值依然为 -1
  • 接下来就是 s[i]t[j + 1] (因为 j-1 开始的)进行比较:
    • 如果 s[i]t[j + 1] 不相同,j 就要从 next 数组里寻找下一个匹配的位置;
    • 如果 s[i]t[j + 1] 相同,那么 ij 同时向后移动。
  • 如果 j 指向了模式串 t 的末尾,那么就说明模式串 t 完全匹配文本串 s 里的某个子串了。
int strStr(string haystack, string needle) {
	if (needle.size() == 0) {
	    return 0;
	}
	int next[needle.size()];
	getNext(next, needle);
	int j = -1; // // 因为next数组里记录的起始位置为-1
	for (int i = 0; i < haystack.size(); i++) { // 注意i就从0开始
	    while(j >= 0 && haystack[i] != needle[j + 1]) { // 不匹配
	        j = next[j]; // j 寻找之前匹配的位置
	    }
	    if (haystack[i] == needle[j + 1]) { // 匹配,j和i同时向后移动
	        j++; // i的增加在for循环里
	    }
	    if (j == (needle.size() - 1) ) { // 文本串s里出现了模式串t
	        return (i - needle.size() + 1);
	    }
	}
	return -1;
}

匹配过程如下:
在这里插入图片描述

时间复杂度: O ( n + m ) O(n + m) O(n+m)
空间复杂度: O ( m ) O(m) O(m), 只需要保存字符串 needle 的前缀表。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!

注:仅供学习参考,如有不足,欢迎指正!

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

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

相关文章

基于SSM+Vue的旅游资源网站设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

我们不打价格战!大众的倔强

2023年即将过半&#xff0c;在价格战席卷市场的同时&#xff0c;汽车制造商必须在市场份额、销量、营收以及利润之间做出权衡。“无论如何&#xff0c;大众都不会参与中国市场的价格战。“本周&#xff0c;大众汽车首席运营官Ralf Brandstaetter表示。 这家曾经在中国市场长期占…

留学生ChatGPT的正确打开方式及推荐使用方式

ChatGPT是什么? ChatGPT可以代写论文吗&#xff1f; ChatGPT推荐打开方式是什么&#xff1f; 今天就为大家梳理一下火爆全网的ChatGPT在留学中的正确打开方式&#xff0c;让同学可以更好地体验ChatGPT带来的便利。 什么是Chat GPT&#xff1f; ChatGPT&#xff08;Chat G…

Office Visio 2016安装

哈喽&#xff0c;大家好。今天一起学习的是Visio 2016的安装&#xff0c;这是一个绘制流程图的软件&#xff0c;用有效的绘图表达信息&#xff0c;比任何文字都更加形象和直观。Office Visio 是office软件系列中负责绘制流程图和示意图的软件&#xff0c;便于IT和商务人员就复杂…

微信电脑版二维码( NATIVE 扫码支付)

后端代码 /** * 微信支付->扫码支付(模式二)->统一下单->微信二维码 * return */ PostMapping (value “/qrcode”) RequestLog(“微信支付二维码”) ApiOperation(“微信支付二维码”) AnonAccess public ResponseEntity wxpayPay(Validated RequestBody SysMember…

GreatSQL 8.0.32-24 今日发布

1.新增特性 1.1 SQL兼容性1.2 MGR1.3 性能优化1.4 安全 2.稳定性提升 3.其他调整 4.bug修复 5.GreatSQL VS MySQL 6.GreatSQL Release Notes GreatSQL 8.0.32-24版本发布&#xff0c;增加并行load data、&#xff08;逻辑 & CLONE&#xff09;备份加密、MGR读写节点可绑定…

MyBatis的创建和单表使用

前言&#xff1a; 之前我们了解到MySQL。接下来了解一下MyBatis&#xff0c;它不是一种数据库&#xff0c;那是什么呢和数据库有什么联系了&#xff1f; 目录 一&#xff1a;MyBatis的定义 二&#xff1a;MyBatis的创建 三&#xff1a;MyBatis的简单使用 3.1:准备工作 3.…

后端服务架构高性能设计之道

“N 高 N 可”&#xff0c;高性能、高并发、高可用、高可靠、可扩展、可维护、可用性等是后台开发耳熟能详的词了&#xff0c;它们中有些词在大部分情况下表达相近意思。本序列文章旨在探讨和总结后台架构设计中常用的技术和方法&#xff0c;并归纳成一套方法论。 前言 本文主…

视频采集到录制 - MP4生成

录制最终格式是MP4&#xff0c;视频流是采用H264编码流&#xff0c;音频是aac编码流 最终需要将两个流合并到一个文件里 采用的方案&#xff0c;是通过mp4v2的库&#xff0c;进行合并 原理很简单&#xff1a; 先创建文件&#xff0c;输入编码参数 需要创建视频流初始 也需要…

制造业在数字化时代如何应对挑战和机遇?

随着数字化时代的到来&#xff0c;制造业不可避免地会受到一些对应的挑战和机遇。以下是一些关键部分&#xff1a; 数字化转型&#xff1a;制造商已经采用数字技术来转变他们的运营。包括采用高级分析、自动化、人工智能 (AI) 和物联网 (IoT)。这些技术可以提高生产力、质量控制…

2.项目数仓、项目工具

项目数仓 数仓(Data Warehouse)是指用于存储和管理企业数据的一种大型数据库系统,以支持企业的决策分析活动。它采用了ETL(抽取、转化、加载)等技术来集成和清洗数据,并提供了灵活的查询和报表功能,使得分析师和决策者可以更好地理解企业的业务情况和趋势。 项目工…

基于三相坐标系状态方程的感应电动机起动动态计算(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

DataGrip使用技巧总结

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

照片怎么拼图?简单好用的拼图方法分享

照片的拼接不仅能够让我们将多张照片合成一张大图&#xff0c;还能够发挥我们的想象和创意&#xff0c;例如&#xff0c;我们可以将不同的照片拼接在一起&#xff0c;创造出一个全新的场景&#xff0c;或者将同一个场景的不同角度的照片拼接在一起&#xff0c;制作出一个完整的…

一个网站建设公司如何保障提供优质的服务

网站建设公司提供的服务是否优质&#xff0c;直接影响到客户的口碑&#xff0c;也会影响到公司的口碑。 一个好的网站建设公司&#xff0c;不仅会提供优质的服务&#xff0c;还会有专业的技术人员对客户进行跟踪服务。这是一项重要的工作&#xff0c;需要一个网站建设公司不断…

《神奇的连接组》读后

人类大脑被戏称为“三磅的宇宙”&#xff0c;或许可以从科学上解释关于“意识”的问题&#xff0c;大脑的神经科学可能是人类科学的最终前沿。 任何真正先进的科技&#xff0c;看起来都与魔法无异。 要解释大脑如何运转&#xff0c;单凭基因无法解释大脑为什么这样工作&#xf…

Java——Java易错选择题复习(2)(计算机网络)

1. 下面关于源端口地址和目标端口地址的描述中&#xff0c;正确的是&#xff08; &#xff09; A. 在TCP/UDP传输段中&#xff0c;源端口地址和目的端口地址是不能相同的 B. 在TCP/UDP传输段中&#xff0c;源端口地址和目的端口地址必须是相同的 C. 在TCP/UDP传输段中&#xff…

chatgpt赋能python:Python声音处理之变声

Python声音处理之变声 随着科技的发展&#xff0c;人们对于声音处理越来越感兴趣。变声技术就是其中的一种&#xff0c;它可以将一个人的声音变成其他的人或动物的声音&#xff0c;非常有趣。 Python作为一种广泛使用的编程语言&#xff0c;可以在声音处理中发挥重要作用。本…

如何在食品行业运用IPD?

食品是我国重要的民生产业之一&#xff0c;是保障和满足人民群众不断增长消费需求的重要支撑。食品指各种供人食用或者饮用的成品和原料以及按照传统既是食品又是药品的物品&#xff0c;包括加工食品&#xff0c;半成品和未加工食品&#xff0c;不包括烟草或只作药品用的物质。…

为数据可视化增添戏剧性

Python 中的视觉叙事&#xff1a;让数据说话的 5 个创新技巧 为数据可视化增添戏剧性 数据可视化 - 这是一个现在经常被抛出的短语。但我们谈论的不仅仅是普通的旧图表和图形。 不 不 不。我们谈论的是讲故事。我们正在谈论将这些行和列的数字变成令人着迷的叙述。 现在是我们从…