数据结构与算法学习笔记----KMP

数据结构与算法学习笔记----KMP

@@ author: 明月清了个风

@@ last edited: 2024.11.24

Acwing 831. KMP字符串

给定一个字符串 S S S,以及一个模式串 P P P,所有字符串中只包含大小写英文字母以及阿拉伯数字。

模式串 P P P在字符串 S S S中多次作为子串出现。

求出模式串 P P P在字符串 S S S中所有出现的位置的起始下标。

输入格式

第一行包含整数 N N N,表示字符串 P P P的长度。

第二行输入字符串 P P P

第三行输入整数 M M M,表示字符串 S S S的长度。

第四行输入字符串 S S S

输出格式

共一行,输出所有出现位置的起始下标(下标从 0 0 0开始计数),整数之间用空格隔开。

数据范围

1 ≤ N ≤ 1 0 5 1 \leq N \leq 10^{5} 1N105,

1 ≤ M ≤ 1 0 6 1 \leq M \leq 10^{6} 1M106

思路

首先考虑暴力做法,两重循环即可完成,伪代码如下:

...  //  原字符串为S,模式串为Pfor(int i = 0; i < n; i ++)  // 循环字符串S{bool flag = false;int temp = i;  // 存这一轮匹配的起始位置for(int j = 0; j < m;)  // 循环模式串P{while(s[i] == p[j] && j < m) i ++, j ++;if(j == m) flag = true; // 将模式串P循环到底说明这轮匹配成功else break;  // 否则表示这一轮匹配失败,直接跳出。}if(flag) cout << temp << ' ';i = temp;  }
...

时间复杂度为:O(n * m)

这里模拟KMP的暴力匹配过程,字符串 S S S P P P中的元素分别用 a i a_{i} ai b i b_{i} bi表示:

  1. 假设目前已经匹配完成的是 a i a_{i} ai b j b_{j} bj,也就是说字符串 S S S中的[1 ~ i]与模式串 P P P中的[1 ~ j]相等,即图中红框中的两部分相等
    在这里插入图片描述

  2. a i + 1 a_{i+1} ai+1 b j + 1 b_{j + 1} bj+1不相等时,此时匹配失败(如图中紫色虚线框中),那么此时需要将模式串 P P P向后移动,暴力做法中应移动一位,若此时字符串 S S S[2 ~ i]项与模式串 P P P[1 ~ j - 1]项能够匹配成功也就意味着,对于模式串 P P P而言,其前 [1 ~ j]项中前缀[1 ~ j - 1]项与后缀[2 ~ j]项是相等的(由一步的图中可以知道字符串 S S S中的[2 ~ i]项等于模式串 P P P中的[2 ~ j]项)
    在这里插入图片描述

那么如果对于模式串而言,若其前 [1 ~ j]项中前缀[1 ~ j - 1]项与后缀[2 ~ j]项不相等,相等的是前缀[1 ~ j - 2]与后缀[3 ~ j],那么就会出现下图的情况:
在这里插入图片描述
当暴力匹配第一步匹配到 a i + 1 a_{i+1} ai+1失败后,试图将模式串向后移动一位重新匹配,但是肯定匹配未到 a i + 1 a_{i+1} ai+1就会失败(因为其前 [1 ~ j]项中前缀[1 ~ j - 1]项与后缀[2 ~ j]项不相等),因此继续向后移动一位,因为此时模式串 P P P中前缀[1 ~ j - 2]与后缀[3 ~ j]相等,因此可以直接继续匹配 a i + 1 a_{i+1} ai+1,图中所示的第二步就是可被优化掉的操作,也就是跳过一定不可能匹配成功的位置。

综上所述可以得出优化暴力做法的思路:针对模式串 P P P预处理出其以第一项为头的所有长度的连续子串的最大的相同前后缀子串。
解释一下这句话:

  1. 因为模式串 P P P需要完整匹配,因此总是需要从第一项开始匹配
  2. 当匹配到某一个位置失败后,因为前面的都已与字符串 S S S匹配成功,且被匹配字符串 S S S不动,那么此时将模式串 P P P向后移动就相当于用模式串 P P P去匹配自己的后缀,那么为了减少匹配次数,假设匹配失败位置是 b i b_{i} bi,那么只要知道模式串 P P P的以第一项 b 1 b_{1} b1为头到 b i − 1 b_{i-1} bi1这个子串(即子串 b 1 ∼ i − 1 b_{1 \sim i-1} b1i1)的最大相同前后缀即可直接继续匹配 b i b_{i} bi,若仍不匹配,继续递归即可。

优化后的KMP算法时间复杂度为O(m + n)

代码

#include <iostream>using namespace std;const int N = 100010, M = 1000010;int n, m;
char s[M], p[N];
int ne[N];int main()
{cin >> n >> p + 1 >> m >> s + 1;for(int i = 2, j = 0; i <= n; i ++){while(j && p[i] != p[j + 1]) j = ne[j];if(p[i] == p[j + 1]) j ++;ne[i] = j;}for(int i = 1, j = 0; i <= m; i ++){while(j && s[i] != p[j + 1]) j = ne[j];if(s[i] == p[j + 1]) j ++;if(j == n){cout << i - n << ' ';j = ne[j];}}return 0;
}

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

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

相关文章

算法基础 - 二分迭代法求解非线性方程

文章目录 1. 基本思想2. 编程实现2.1. 非递归2.2. 递归方案 3. 总结 二分迭代法使用了二分算法思想求解非线性方程式。 下面要求使用二分迭代法求解&#xff1a; 2x3-5x-10 方程式&#xff0c;且要求误差不能大于10e-5。 二分迭代法也只是近似求解算法。 所谓求解&#xff…

家校通小程序实战教程03学生管理

目录 1 创建数据源2 搭建后台功能3 设置主列字段4 批量导入数据5 设置查询条件6 实现查询和重置总结 我们现在已经搭建了班级管理&#xff0c;并且录入了班级口令。之后就是加入班级的功能了。这里分为老师加入班级和学生家长加入班级。 如果是学生家长的话&#xff0c;在加入之…

springboot336社区物资交易互助平台pf(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 社区物资交易互助平台设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff…

【C++】7000字介绍map容器和set容器的功能和使用

目录 一、关联式容器和序列式容器 二、键值对,> 三、树形结构的关联式容器 四、set容器&#xff08;key模型&#xff09; 1、文档官网 2、功能介绍&#xff1a; 3、注意事项&#xff1a; 4、基本使用&#xff0c;更多接口可查看官网&#xff1a; &#xff08;1&…

嵌入式C语言技巧15:深入浅出:多线程编程中锁的选择与优化策略

文章目录 导读一、锁机制概览二、实战演练:锁的选择与使用三、代码执行结果与分析四、总结与展望本文是经过严格查阅相关权威文献和资料,形成的专业的可靠的内容。全文数据都有据可依,可回溯。特别申明:数据和资料已获得授权。本文内容,不涉及任何偏颇观点,用中立态度客观…

【Git】常用命令汇总

目录 一.安装及配置 1.在 Windows 上安装 2.用户信息 3.差异分析工具 二.基础 1.创建仓库 2.提交与修改 三.分支管理 1.创建分支 2.合并分支 四.远程操作 1.管理 Git 仓库中的远程仓库 2.数据的获取与推送 五.标签 1.创建轻量标签和附注标签 2.查看标签和标签信…

AWS海外注册域名是否需要实名认证?

在全球化的互联网环境中&#xff0c;注册域名已成为企业和个人建立在线存在的重要步骤。亚马逊网络服务&#xff08;AWS&#xff09;作为全球领先的云服务提供商&#xff0c;其域名注册服务也备受关注。然而&#xff0c;对于在AWS上注册海外域名是否需要实名认证&#xff0c;许…

【C++进阶篇】像传承家族宝藏一样理解C++继承

文章目录 须知 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&#xff1…

DAMODEL丹摩|部署FLUX.1+ComfyUI实战教程

本文仅做测评体验&#xff0c;非广告。 文章目录 1. FLUX.1简介2. 实战2. 1 创建资源2. 1 ComfyUI的部署操作2. 3 部署FLUX.1 3. 测试5. 释放资源4. 结语 1. FLUX.1简介 FLUX.1是由黑森林实验室&#xff08;Black Forest Labs&#xff09;开发的开源AI图像生成模型。它拥有12…

具体的技术和工具在县级融媒体建设3.0中有哪些应用?

以下是结合数据来看县级融媒体建设3.0的一些情况&#xff1a; 技术应用方面 大数据&#xff1a;人民网舆情数据中心执行主任董盟君提到&#xff0c;通过大数据分析可让融媒体单位快速关注聚焦点&#xff0c;实现智能策划、智能推送、智能传播&#xff0c;推动媒体传播影响力提…

中兴机顶盒B860AV1.1刷机固件升级和教程「适用4/8G版」

准备工作&#xff1a; TTL 线&#xff08;CH340G 按系统版本找到要对应驱动&#xff09;下载 putty 软件拆开电视盒接好 TTL 线&#xff08;2、5、6 针脚对应GND、RX、TX&#xff09;在资源管理器的端口选项下找到 CH340G&#xff0c;记住端口号&#xff08;如 COM4&#xff0…

SeggisV1.0 遥感影像分割软件【源代码】讲解

在此基础上进行二次开发&#xff0c;开发自己的软件&#xff0c;例如&#xff1a;【1】无人机及个人私有影像识别【2】离线使用【3】变化监测模型集成【4】个人私有分割模型集成等等&#xff0c;不管是您用来个人学习 还是公司研发需求&#xff0c;都相当合适&#xff0c;包您满…

QINQ技术

定义 QINQ即802.1q in 802.1q&#xff0c;因为IEEE802.1Q中定义的Vlan Tag域只有12个比特&#xff0c;仅能表示4096个Vlan&#xff0c;随网络发展被用尽&#xff0c;于是在原有带vlan的数据上再携带一层vlan标签用于扩展vlan数目。一般来说外层vlan是公网&#xff0c;内层是私…

linux基础2

声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

鸿蒙千帆启新程,共绘数字生态蓝图

华为的鸿蒙千帆起计划&#xff1a;共筑数字未来&#xff0c;学习华为创新之路 在当今全球科技竞争日益激烈的背景下&#xff0c;华为作为中国科技企业的代表&#xff0c;正通过其自主创新的鸿蒙系统&#xff0c;引领一场移动应用生态的变革。鸿蒙千帆起计划&#xff0c;作为华…

Qt-系统相关(2)多线程网络

Qt多线程 在 Qt 中&#xff0c;多线程的处理⼀般是通过 QThread类 来实现。 QThread 代表⼀个在应⽤程序中可以独⽴控制的线程&#xff0c;也可以和进程中的其他线程共享数据。 QThread 对象管理程序中的⼀个控制线程。 QThread 常⽤ API&#xff1a; 使用线程 关于创建线程…

永久免费的PDF万能水印删除工具

永久免费的PDF万能水印删除工具 1.简介 PDF万能水印删除工具&#xff0c;可以去除99.9%的PDF水印。例如&#xff1a;XObject水印&#xff08;含图片水印&#xff09;、文本水印、绘图水印/曲线水印、注释水印、工件水印、剪切路径水印等等。本软件是永久免费&#xff0c;无有…

华三(HCL)和华为(eNSP)模拟器共存安装手册

接上章叙述&#xff0c;解决同一台PC上同时部署华三(HCL)和华为(eNSP&#xff09;模拟器。原因就是华三HCL 的老版本如v2及以下使用VirtualBox v5版本&#xff0c;可以直接和eNSP兼容Oracle VirtualBox&#xff0c;而其他版本均使用Oracle VirtualBox v6以上的版本&#xff0c;…

深度理解进程的概念(Linux)

目录 一、冯诺依曼体系 二、操作系统(OS) 设计操作系统的目的 核心功能 系统调用 三、进程的概念与基本操作 简介 查看进程 通过系统调用获取进程标识符 通过系统调用创建进程——fork() 四、进程的状态 操作系统中的运行、阻塞和挂起 理解linux内核链表 Linux的进…

SQLite 管理工具 SQLiteStudio 3.4.5 发布

SQLiteStudio 3.4.5 版本现已发布&#xff0c;它带来了大量的 bug 修复&#xff0c;并增加了一些小功能。SQLiteStudio 是一个跨平台的 SQLite 数据库的管理工具。 具体更新内容包括&#xff1a; 现在可以使用 Collations Editor 窗口在数据库中注册 Extension-based collatio…