串的模式匹配(简单匹配、KMP以及手工算next/nextval)

简单模式匹配

        思路:主串和字串进行匹配,设置i、j、k(主串、子串和匹配起始下标)主串和子串一开始都是从第一个位置(k = i),若当前主串和子串匹配成功那么i++、j++,若匹配不成功k++、j = 1,i = k(主串从上次匹配的下一个开始,子串回到第一个字符)重复以上步骤。若是匹配成功,则返回子串在主串中的位置(k),若是匹配不成功,则返回一个可以区别于主串所有标记的位置,比如 0.

#include<iostream>
#include<string>
using namespace std;
/*
思路:主串和字串进行匹配,设置i、j、k(主串、子串和匹配起始下标)
主串和子串一开始都是从第一个位置(k = i),若当前主串和子串匹配成功那么i++、j++,
若匹配不成功k++、j = 1,i = k(主串从上次匹配的下一个开始,子串回到第一个字符)
重复以上步骤。若是匹配成功,则返回子串在主串中的位置(k),若是匹配不成功,
则返回一个可以区别于主串所有标记的位置,比如 0.
*/
int index(string str, string substr) {int i = 1, j = 1, k = i; // 这里规定字符串从第一个开始,比较好操作if (str.length() == 1 || substr.length() == 1) return 0;// 主串或者子串为空的情况下while (i < str.length() && j < substr.length()) { // i,j都没有遍历到结尾if (str[i] == str[j]) { // 若匹配i++;j++;}else { // 若不匹配k++;j = 1;i = k;}}if (j > substr.length()) { // 匹配成功return k;}return 0;
}

KMP匹配

简单匹配的缺点

        KMP与简单匹配的区别在于如何利用已知且匹配好的模式串,简单匹配每当匹配到不匹配的位置时一律将 i 赋值为 i - j + 2 ,j 赋值为 1。这样的坏处就在于①不匹配的地方不被解决②不匹配的地方任然存在。显然这样暴力求解的方法简单但不高效。

KMP匹配思想

        KMP关键在于如何利用已知已匹配成功的部分模式串,而主串是何种形式并不关心。KMP模式匹配中每当遇到不匹配的位置,我们往前看以匹配好的部分串,如果以匹配成功的模式串的部分串中,存在与不匹配位置(不匹配位置前面)相等的后缀,那么我们就移动模式串(难以理解,看下图)

        假设模式串从第一个字符到不匹配的字符之前的部分串为 F 而 与不匹配位置开始的前缀为 G,与 G 匹配相等的模式串某后缀为 H ,我们要做的就是将 F 后移直到 G 与 H 重合,H 的下一个位置则为模式串需要跳转比较的新位置,为了记录这些新位置我们引入 next[]数组以记录发生不匹配的情况时 j 跳转的位置。

手工算next数组

        说明第一个位置(特殊情况一)不匹配时,i 赋值为 0,j 赋值为 0,然后 i++, j++;

        第二个位置不匹配时(特殊情况二),i 保持不变,j = 1,然后 i++, j++;

直到最后 j > substr.length() 退出循环。

另一个例子如下:

        参照以上方法,写下一下例子的答案:

KMP实现代码
#include<iostream>
#include<string>
using namespace std;// 获取next数组
void getNext(string substr, int next[]) {	int i = 1, j = 0; // 模式串从第一个字符串开始,数组下标从 1 开始next[1] = 0;while (i <= substr.length()) {// 取到最后一个串if (j == 0 || substr[i] == substr[j]) { // j退回到0时,和 i 一起向后移++i;++j;next[i] = j;}else {j = next[j];}} 
}int KMP(string str, string substr, int next[]) {// 先获取模式串getNext(substr, next);int i = 1, j = 1; // 模式串从0开始if (str.length() == 1 || substr.length() == 1) return 0;// 主串或者子串为空的情况下while (i <= str.length() && j <= substr.length()) {if (j == 0 ||str[i] == substr[j]) { // 若匹配成功i++;j++;}else {j = next[j];}}if (j > substr.length()) { // 匹配成功return i - substr.length(); // 返回匹配的初始位置}return 0;
}

进一步的KMP匹配

        观察以上手工算next数组的第一个例子,我们会发现当发生不匹配的字符与 next 数组所指的字符相同时,跳转后不匹配仍然存在,且后续还需要跳转,这样就需要跳转两次。那我们能不能只跳转一次呢?这样就引入了nextval 数组,nextval 数组的引入是为了解决上述现象,使得KMP匹配算法更加高效,那么如何计算 nextval 数组呢?看下图👇

👆的例子有点特殊,我们看另一个例子👇

        总之:nextval 数组计算的一般规律是,在计算出 next 数组之后,观察当前 next 和需要跳转的下一个位置的所对应的字符是否相等,若相等那么 nextval[j]等于需要跳转后的那个位置的 next 值(结合上面的例子看),若不相等那么 nextval[j]= next[j]的值.

改进KMP代码
#include<iostream>
#include<string>
using namespace std;void getNextval(string substr, int nextval[]) {if (substr.length() == 1) return; // 主串或者子串为空的情况下int i = 1, j = 1; // nextvl也是从1开始nextval[1] = 0; // 特殊位置while (i <= substr.length()) {if (j == 0 || substr[i] == substr[j]) {++i; ++j;if (nextval[i] != nextval[j]) { // i、j处字符不相等nextval[i] = j; // 当前需要跳转的位置}else {// i 、j所指字符相等nextval[i] = nextval[j]; // 需要跳转后位置的跳转位置}}}
}

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

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

相关文章

叶顺舟:手机SoC音频趋势洞察与端侧AI技术探讨 | 演讲嘉宾公布

后续将陆续揭秘更多演讲嘉宾&#xff01; 请持续关注&#xff01; 2024中国国际音频产业大会(GAS)将于2024年3.27 - 28日在上海张江科学会堂举办。大会将以“音无界&#xff0c;未来&#xff08;Audio&#xff0c; Future&#xff09;”为主题。大会由中国电子音响行业协会、上…

22 OpenCV 直方图计算

文章目录 直方图概念split 通道分离函数calcHist 计算直方图normalize 归一化函数示例 直方图概念 上述直方图概念是基于图像像素值&#xff0c;其实对图像梯度、每个像素的角度、等一切图像的属性值&#xff0c;我们都可以建立直方图。这个才是直方图的概念真正意义&#xff0…

HarmonyOS鸿蒙开发常用4种布局详细说明

介绍一下鸿蒙开发常用4种布局 1、线性布局 2、层叠布局 3、网格布局 4、列表布局 ​1. 线性布局&#xff08;Column/Row&#xff09; 线性布局&#xff08;LinearLayout&#xff09;是开发中最常用的布局&#xff0c;通过线性容器Row&#xff08;行&#xff09;和Column&…

软件杯 深度学习 python opencv 动物识别与检测

文章目录 0 前言1 深度学习实现动物识别与检测2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存…

网络原理(2)——TCP协议

目录 一、TCP协议段格式 二、确认应答 三、超时重传 TCP全称为&#xff1a;"传输控制协议 Transmission Control Protocol)"。协议如其名&#xff0c;要对数据的传输进行一个详细的控制。 一、TCP协议段格式 源 / 目的端口号&#xff1a;表示数据从哪个进程来&am…

【Web开发】CSS教学(超详细,满满的干货)

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【Web开发】CSS教学(超详细,满满的干货) &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 CSS一. 什么是CSS?1.1 基本语法规范1.2 引入方式1.3 规范 二. CSS选…

第三篇 - 概述- IAB受众和技术标准 - IAB视频广告标准《数字视频和有线电视广告格式指南》

第三篇 - 概述- IAB受众和技术标准​​​​​​​ - 我为什么要翻译介绍美国人工智能科技公司IAB技术标准系列&#xff08;2&#xff09; 本文目录 一、IAB技术实验室简介 二、概述及IAB受众 三、资源- IAB倡导的相关视频广告技术标准 四、案例分享-介绍一家数字化营销服务…

MySQL中出现‘max_allowed_packet‘ variable.如何解决

默认情况下&#xff0c;MySQL的max_allowed_packet参数可能设置得相对较小&#xff0c;这对于大多数常规操作来说足够了。但是&#xff0c;当你尝试执行包含大量数据的操作&#xff08;如大批量插入或大型查询&#xff09;时&#xff0c;可能会超过这个限制&#xff0c;从而导致…

YOLOv9详解

1.概述 在逐层进行特征提取和空间转换的过程中&#xff0c;会损失大量信息&#xff0c;例如图中的马在建模过程中逐渐变得模糊&#xff0c;从而影响到最终的性能。YOLOv9尝试使用可编程梯度信息PGI解决这一问题。 具体来说&#xff0c; PGI包含三个部分&#xff0c;&#xff0…

bugku-easy_nbt

解压文件得到 感觉dat文件可疑&#xff0c;尝试修改为zip文件 解压level&#xff0c;然后用010打开 搜索得到flag

【数据结构七】堆与PriorityQueue详解

堆 在Java中有一种数据结构基于队列&#xff0c;并保证操作的数据带有优先级&#xff0c;该数据结构应该提供了两个最基本的操作&#xff0c;一个是返回最高优先级对象&#xff0c;一个是添加新的对象。这种数据结构就是优先级队列(Priority Queue)。它的底层使用了堆这种数据结…

软考高级:软件工程单元测试(驱动模块、被测模块、桩模块)概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

吴恩达机器学习-可选实验室:神经元和层(Neurons and Layers)

文章目录 可选实验室&#xff1a;神经元和层包无激活神经元-回归/线性模型Sigmoid激活的神经元祝贺 可选实验室&#xff1a;神经元和层 实验室将探索神经元和层的内部工作原理&#xff0c;特别是将课程1中掌握的模型&#xff0c;即回归/线性模型和逻辑斯蒂模型&#xff0c;与之…

2024年腾讯云个人用户免费服务器配置和申请说明

腾讯云免费服务器申请入口 https://curl.qcloud.com/FJhqoVDP 免费服务器可选轻量应用服务器和云服务器CVM&#xff0c;轻量配置可选2核2G3M、2核8G7M和4核8G12M&#xff0c;CVM云服务器可选2核2G3M和2核4G3M配置&#xff0c;腾讯云服务器网txyfwq.com分享2024年最新腾讯云免费…

《AcWing第147场周赛》 牛的语言学(递推) / 孤立点数量(并查集)

文章目录 牛的语言学考察知识&#xff1a;递推 题目链接题目描述思路具体代码及注释 孤立点数量考察知识&#xff1a;并查集 题目链接题目描述思路分析 在这里插入图片描述代码及注释 牛的语言学 考察知识&#xff1a;递推 题目链接 https://www.acwing.com/problem/content…

【网络原理】TCP协议详细解析

文章目录 &#x1f332;TCP协议的概念&#x1f338;TCP协议段格式&#x1f338;TCP的特性 &#x1f333;TCP原理详解&#x1f338;确认应答机制&#xff08;安全机制&#xff09;&#x1f338;超时重传机制&#xff08;安全机制&#xff09;&#x1f338;连接管理&#xff08;安…

【软考高项】七、信息技术发展之存储、数据库、信息安全

1、存储知识点 存储类型分&#xff1a;封闭式&#xff08;小型机&#xff09;和开放式&#xff08;服务器&#xff09; 其中开放式又分内置和外挂存储&#xff08;直连DAS、网格FAS&#xff08;NAS/SAN&#xff09;&#xff09; 2、数据库知识点 数据结构模型&#xff1a; …

MyBatisPlus 之一:Spring 整合 MyBatisPlus 及雪花算法

1. Mybatis-Plus简介 Mybatis-Plus&#xff08;简称MP&#xff09;是一个 Mybatis 的增强工具&#xff0c;在 Mybatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。这是官方给的定义&#xff0c;关于mybatis-plus的更多介绍及特性&#xff0c;可以参考http…

蓝桥杯第 6 场 小白入门赛 2.猜灯谜(for + 数组)

思路&#xff1a;注意是环形排列的灯笼&#xff0c;它的谜底是相邻两个灯笼的数字之和。这道题要用到两个数组&#xff0c;ans存答案&#xff0c;a存原数据。数据读入部分就不用说了&#xff0c;重点就是单独写明ans[0]和ans[n-1]两个取值&#xff0c;其他的用for循环数组就可以…

数据结构——栈和队列的表示与实现详解

目录 1.栈的定义与特点 2.队列的定义与特点 3.案例引入 4.栈的表示和操作的实现 1.顺序栈的表示 代码示例&#xff1a; 2.顺序栈的初始化 代码示例&#xff1a; 3.判断栈是否为空 代码示例&#xff1a; 4.求顺序栈长度 代码示例&#xff1a; 5.清空顺序栈 …