C++基础:KMP

news2025/8/18 15:46:05

让我们先看一个问题:

给定一个字符串 S,以及一个模式串 P,所有字符串中只包含大小写英文字母以及阿拉伯数字。
模式串 P 在字符串 S 中多次作为子串出现。
求出模式串 P 在字符串 S 中所有出现的位置的起始下标。
输入格式
第一行输入整数 N,表示字符串 P 的长度。
第二行输入字符串 P
第三行输入整数 M,表示字符串 S 的长度。
第四行输入字符串 S
输出格式
共一行,输出所有出现位置的起始下标(下标从 0 开始计数),整数之间用空格隔开。
数据范围
1≤N≤10 5
1≤M≤10 6
输入样例:
3
aba
5
ababa
输出样例:
0 2

这就是著名的KMP问题

朴素的做法

我们先考虑最朴素的做法:

我们将P与S一一对应的去判断,若当前的p[i]≠s[j],那么就将p往后面挪一位,继续与S一一对应的去判断。这个算法很好想,也很超时,别用这个。

经典KMP算法

我们观察到朴素做法中当p[i]≠s[j]时我们只挪了P往后1位,那没有么有方法让P多往后移动几位?

第一步

这一步称之为匹配

首先定义next[i]=j意思是P数组中下标1~j的元素与下标(i-j+1)~i的元素相同,即从1开始长度为j的前缀=从i开始长度为j的后缀

别慌,举个例子你就懂了

P=abcabd(下标从1开始)

next[5]=2 意思是P数组中下标1~2的元素(ab)与下标4(即5-2+1)~5的元素(ab)相等

也就是说,当p[i]≠s[j+1]时(这里j+1你到时候看代码就懂了,只是为了写代码方便,注意红圈是j+1啊!!!,他前面的绿线才是j)

如果橙色这一段=黑色这一段(见下图的①,P段),那么我们就不将P平移1个单位,我们直接将①段平移到②段,即点a平移到了a`,b平移到了b`,大家可以想一想(结合我画的两条黑线),就可以得出②此时在长的绿色线之前的那一段是与蓝色线(S)的元素是相等的。大家可以自己画图来理解。

结合上述对next数组的定义,我们可以得到每次当出现①的情况时,我们将b平移到b`,相当于进行一个操作:j=next[j]。这块大家可以画画图理解一下,自己可以举几个实例,勤于动笔才能懂!

第二步

那么该怎么求next数组呢???

我们可以换一个角度分析

假设字符串S=P,那么我们先进行第一步操作,然后让next[i]=j就行了,这一段没有什么解释的必要,主要是跟第一步没多少区别,只是多了一步next[i]=j,不懂的话大家看看代码演算一下

代码

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

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

相关文章

【Python】杨辉三角中的排成一列编号的问题

题目描述 下面的图形是著名的杨辉三角形: 如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列: 1,1,1,1,2,1,1,3,3,1,1,4,6,4,1,⋯ 给定一个正整数 N,请你输出数列中第一次出现 N是在第几个数? …

Go语言设计与实现 -- 内存管理器

不同的编程语言选择不同的方式管理内存,本节会介绍Go语言内存分配器。 Go内存分配的设计思想是: 内存分配算法采用Google的TCMalloc算法,每个线程都会自行维护一个独立的内存池,进行内存分配时优先从该内存池中分配,…

第十八章Vue的学习

文章目录什么是VueVue.js的官网介绍环境配置基本语法声明式渲染绑定元素属性双向数据绑定条件渲染列表渲染事件驱动侦听属性Vue对象生命周期什么是Vue 对于Java程序来说,我们使用框架就是导入那些封装了**『固定解决方案』的jar包,然后通过『配置文件』…

CSS3 之选择器

文章目录1、关系性选择器:EFE~F2、属性选择器3、伪元素选择器4、伪类选择器(被选中的元素的一个种状态)calc1、关系性选择器:EFE~F 2、属性选择器 E[attr~“val”]E[attr|“val”]E[attr^“val”]E[attr$“val”]E[attr*“val”]3、伪元素选择器 E::pl…

CesiumLab对BIM模型的输入格式要求 CesiumaLab系列教程

BIM 模型和手工模型最大的区别在于几点: 1.建模目标不同,手工模型的目的是为了可视化,就是为了看的见,看不见的东西能省则省。BIM 完全是按照一些工程标准去创建的,比如路面可能有多个层代表了不同的物理层。手工模型…

windows编译Paraview源码

目录一. 环境准备二. 编译1. CMake2. Visual Studio一. 环境准备 下载基本所需: paraview官方给了编译文档:https://github.com/Kitware/ParaView/blob/master/Documentation/dev/build.md 所需要的基础有: 如图:(进入…

2022我的年度总结-- AI遮天之路

我是一个普普通通的大学生,我的博客记录了我学习编程以来共计1年多的水平,我希望能把自己大学的经历、选择、困惑等与同样身处大学,选择AI方向不知如何发展的人进行分享,因此写了这篇年终总结。另外,对于一些刚刚开始写…

重磅!华为更新职业认证架构刷新和重认证规则

尊敬的各位朋友,感谢您一直以来对华为认证的支持! 为匹配华为公司未来长期战略,紧随ICT技术演进趋势,自2023年1月1日起,华为职业认证将启用全新的架构体系和重认证规则,请您关注。 华为职业认证架构刷新 …

新年新希望--爱摸鱼的美工(12)

年近了,上班途中依然匆忙 看女孩子们渐渐开始倒腾 做了新发型,做了美美的指甲 换上了新衣服,买了新包 电话里讨论着 去哪里过年,买什么年货 好像以前的我也这样 今年挣得少了,不想添新衣(不能) …

【条理清晰】在 Windows 上安装 MySQL

下载 MySQL 安装程序安装 MySQL 数据库安装示例数据库下载 MySQL 安装程序 在本教程中,我们展示如何在 Windows 平台上下载和安装 MySQL 的详细步骤。 在 Windows 平台上安装 MySQL 很简单,并不需要太复杂的步骤。按照本文的步骤操练起来就可以了。 我…

一体化Ethercat通信伺服电机在汇川H5U PLC上的应用案例介绍(下)

内容介绍了一体化低压伺服Ethercat通信的电机在汇川H5UPLC上的使用,一体化Ethercat通信伺服电机在汇川H5U PLC上的应用案例介绍(上)主要讲解环境的搭建以及使用AutoShop软件的在线调试功能,简单控制电机位置、速度模式运行。那么本篇我们就来讲解下使用汇…

【Kotlin】空安全 ② ( 手动空安全管理 | 空安全调用操作符 ? | let 函数结合空安全调用操作符使用 )

文章目录一、手动空安全管理二、空安全调用操作符 ?三、let 函数结合空安全调用操作符使用一、手动空安全管理 Kotlin 语言中 , 变量类型 分为 可空类型 和 非空类型 , 默认状态 下 , 变量是 非空类型 的 , 如果使用 类型? 将变量声明为 可空类型 , 那么就需要使用 手动安…

【C语言进阶】动态内存管理

1. 为什么存在动态内存分配我们已经掌握的内存开辟方式有:int val 20;//在栈空间上开辟四个字节 char arr[10] {0};//在栈空间上开辟10个字节的连续空间但是上述的开辟空间的方式有两个特点:1. 空间开辟大小是固定的。2. 数组在申明的时候,…

JavaWeb复习

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目…

【迅为iMX6Q】开发板 u-boot 2022.04 SD卡 启动

相关参考 【迅为iMX6Q】开发板 u-boot 2015.04 SD卡 启动 【迅为iMX6Q】开发板 u-boot 2020.04 SD卡 启动 开发环境 win10 64位VMware Workstation Pro 16ubuntu 22.04【迅为imx6q】开发板, 2G DDR uboot-imx 下载 使用 NXP 官方提供的 uboot-imx,代…

TreeList-关闭默认显示的右击菜单

需要给控件添加自定义的右击菜单,所以就造成了冲突,导致右击时只弹出控件自带的菜单而没弹出我自定义的菜单,现在把关闭默认菜单的方法记录一下

数据库,计算机网络、操作系统刷题笔记27

数据库,计算机网络、操作系统刷题笔记27 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开的话,你就得学数据库,sql,oracle…

解决在Win10上安装VMware Workstation虚拟机不可用

一、说明 这是近几年安装虚拟机存在的问题,这里首先说明,以下信息纯粹来自VMware的参考文档,本人的实现不太成功,期望得到更好的WMware软件进行尝试。 二、错误提示 在 Windows 10 主机上,VMware Workstation 中显示“…

2023/1/7 Vue学习笔记-3-组件的理解

1 对组件的理解 模块与组件、模块化与组件化: 1.模块: (1)理解:向外提供特定功能的js程序,一般就是一个js文件 (2)为什么:js文件很多很复杂 (3)作…

【Linux工具】-vim介绍

Vim使用一,Vim的四种模式二,命令模式1,复制,剪切,粘贴2,撤销操作3,光标的移动4,替换,选中,删除5,h j k l键的使用6,多行注释,去多行注…