数据结构(四)——串的模式匹配

4.2 串的模式匹配

4.2.1_朴素模式匹配算法

字符串模式匹配:在主串中找到与模式串相同的⼦串,并返回其所在位置

主串⻓度为n,模式串⻓度为 m 朴素模式匹配算法:将主串中所有⻓度为m的⼦串依次与模式串对⽐,直到找到⼀个完全匹配的⼦串, 或所有的⼦串都不匹配为⽌。 最多对⽐ n-m+1 个⼦串 

Index(S,T):定位操作。若主串S中存在与串T值相同的⼦串,则返回它在主串S中第⼀次出现 的位置;否则函数值为0

接下来不使用字符串的基本操作,直接通过数组下标实现朴素模式匹配算法

// 在主串S中找到与模式串T相同的子串并返回其位序,否则返回0
int Index(SString S, SString T){   int i=1, j=1;  while(i<=S.length && j<=T.length){    if(S.ch[i] == T.ch[j]){     //如果i里面存的字符和j里面存的相同的话++i; ++j;     //++继续比较后继字符}else{        i=i-j+2;      //i指针指向下一个子串的起始位置j=1;          //j指针后退回到第一个位置重新开始匹配 }   }   if(j>T.length) return i-T.length;   else       return 0;
}

设主串⻓度为 n,模式串⻓度为 m,则 最坏时间复杂度 = O(nm)

最坏的情况,每个⼦串都要对⽐ m 个字符,共 n-m+1 个⼦串,复杂度 = O((n-m+1)m) = O(nm)

 

4.2.2_1_KMP算法

朴素模式匹配算法的缺点
⼀旦发现当前这个⼦串中某个字符不匹配,就只能转⽽匹配下⼀个⼦串(从头开始)


用代码实现这个处理逻辑 可以用一个next数组来存储让模式串指针指向的位置

next数组只和短短的模式串 有关,和长长的主串⽆关

KMP算法:当子串和模式串不匹配时,主串指针 i 不回溯,模式串指针 j=next[j]。

KMP算法最坏时间复杂度 O(m+n)
其中,求 next 数组时间复杂度 O(m)
模式匹配过程最坏时间复杂度 O(n)

KMP算法的代码实现

// 获取模式串T的next[]数组
void getNext(SString T, int next[]){ int i=1, j=0;  next[1]=0;  while(i<T.length){   if(j==0 || T.ch[1]==T.ch[j]){ ++i; ++j;      next[i]=j;  }else      j=next[j]; }
}// KPM算法,求主串S中模式串T的位序,没有则返回0
int Index_KMP(SString S, SString T){   int i=1, j=1;  int next[T.length+1]; getNext(T, next);  while(i<=S.length && j<=T.length){  if(j==0 || S.ch[i]==T.ch[j]){   //如果主串的元素和模式串的元素相等或j等于0时++i;  ++j;               //i和j++,继续比较后继字符}else   j=next[j];         //模式串向后移动}    if(j>T.length)   return i-T.length;      //j大于模式串长度说明匹配成功elsereturn 0;
}int main() {SString S={"ababcabcd", 9};SString T={"bcd", 3};printf("%d ", Index_KPM(S, T));	//输出9
}


KMP算法精髓:利用已经匹配过的模式串的信息,求出next数组→利用next数组进行匹配(主串指针不回溯)

4.2.2_2_求next数组

next数组的作⽤:当模式串的第 j 个字符失配时,从模式串的第 next[j] 的继续往后匹配

任何模式串第⼀个字符不匹配时,只能匹配下⼀个⼦串,因此,next[1]都⽆脑写 0
第2个字符不匹配时,应尝试匹配模式串的第1个字符, 因此,next[2]都⽆脑写 1
接下来的字符,在不匹配的位置前划一根分界线,模式串一步一步往后退,直到分界线前的“对的上”,或模式串完全越过分界线位置,如下面为第3个字符不匹配的情况
第四个字符不匹配
第五个字符不匹配

第六个字符不匹配


4.2.3_KMP算法的进一步优化


第3个字符和第1个字符相同,所以 可以直接跳到next[1]指向的位置,第5个字符跟第2个字符相同,直接跳到next[2]指向的位置

void getNextval(SString T, int nextval[]){int i=1,j=0;nextval[1]=0;while(i<T.length){if(j==0 || T.ch[i]==T.ch[j]){++i; ++j;if(T.ch[i]!=T.ch[j])nextval[i]=j;elsenextval[i]=nextval[j];}elsej=nextval[j];}
}


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

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

相关文章

代码随想录刷题day27|组合总和II组合总和II分割回文串

文章目录 day27学习内容一、组合总和-所选数字可重复1.1、代码-正确写法1.1.1、为什么递归取的是i而不是i1呢&#xff1f; 二、组合总和II-所选数字不可重复2.1、和39题有什么不同2.2、思路2.2.1、初始化2.2.2、主要步骤2.2.3、回溯函数 backTracking 2.3、正确写法12.3.1、为什…

传值、传址、空间释放详细图解

目录 前言 一.进程 1.1 进程的映射 1.2 进程的虚拟空间 二.函数传参 2.1 函数传参 2.2 函数传值 2.2.1 函数传值案例1 2.2.2 函数传值案例2 2.2.3 返回值为常量 2.3 函数传送地址 2.3 字符串使用 前言 详细介绍函数传值和传地址区别&#xff1a;进行数据操作的区别&#xff0c…

VMware workstation pro 16 虚拟机的安装

VMware workstation pro 16 虚拟机的安装 VMware 16下载VMware 16安装VMware 16许可 VMware 16下载 下载地址&#xff1a; VMware workstation pro 16 官网下载地址 VMware 16安装 安装向导&#xff0c;点击下一步勾选我同意许可协议中的条款&#xff0c;点击下一步 更改安…

被奔驰看上的“人”

上周五&#xff0c;人形机器人公司、NASA 合作伙伴 Apptronik 宣布已与梅赛德斯奔驰&#xff08;以下简称奔驰&#xff09;达成一项商业协议&#xff0c;试点将身高 1.7 米、体重 140 多斤的双足机器人 Apollo 用于制造业。奔驰也成为继宝马、蔚来汽车之后最新尝试人形机器人的…

nodejs实现链接shp的属性信息(替换字段或者追加字段)

写在前面 偶尔听到同事说一个数据处理重复性的流程太多&#xff0c;就了解了下&#xff0c;原来是1份shp数据对应着一个xls属性文件&#xff0c;需要把xls文件里的一部分属性更新到shp的相关字段中&#xff0c;当然这种操作是可以用ArcGIS或者QGIS实现&#xff0c;但是当数据特…

综合交易模型----可转债三低策略实盘qmt版,提供源代码

链接 综合交易模型----可转债三低策略实盘qmt版&#xff0c;提供源代码 (qq.com) 可转债3低策略是指选择正股市值低、转债余额低、溢价率低的可转债进行投资的策略。 市值低&#xff1a;指的是可转债对应的正股市场价值较小&#xff0c;这通常意味着需要较少的资金就可以对股价…

jeecg启动Sentinel 一直是空白页面 解决办法用 外部 Sentinel SpringCloud之Sentinel概述和安装及简单整合

jeecg启动Sentinel 一直是空白页面 解决办法用 外部 Sentinel SpringCloud之Sentinel概述和安装及简单整合 文章目录 jeecg启动Sentinel 一直是空白页面 解决办法用 外部 Sentinel SpringCloud之Sentinel概述和安装及简单整合 Sentinel概述基本介绍 Sentinel安装下载地址: http…

聊聊AI时代学习这件事本身应该发生什么样的变化

随着 AI 大模型 的爆发&#xff0c;我们身处这个时代&#xff0c;应该怎么样去学习去了解这些前言的技术&#xff1f;可能很多人会说我英文不好&#xff0c;我算法不行&#xff0c;无法深入去了解 AI 大模型相关的知识吧&#xff1f; 没关系&#xff0c;其实博主也跟大家一样&…

实在智能Agent——RPA终极进化方向

RPA技术备受瞩目&#xff0c;它通过“机器人”自动化了人力执行的重复性、低复杂度任务&#xff0c;解放了员工并降低了企业成本。RPA机器人全天候运行&#xff0c;避免人为错误&#xff0c;高效处理任务&#xff0c;成为处理事务、操作数据、回应查询的理想选择。在管理后台&a…

第四百一十回

文章目录 1. 概念介绍2. 方法与细节2.1 获取方法2.2 使用细节 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何获取当前系统语言"相关的内容&#xff0c;本章回中将介绍如何获取时间戳.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章…

实体店运营方案大全:从选址到日常管理的全面指导

想开实体店或正在创业的朋友们&#xff0c;大家好&#xff01;今天&#xff0c;我作为一个鲜奶吧5年的创业者&#xff0c;为大家分享一份实体店运营方案大全&#xff0c;涵盖从选址到日常管理的各个方面。我在实体店方面有一些心得体会&#xff0c;今天就来和大家聊聊&#xff…

【软考】系统集成项目管理工程师(十九)收尾管理【1分】

一、项目收尾的内容 二、总结 三、软件后续工作 练一练 【例1-17上】&#xff08;B&#xff09;不属于项目验收的内容。 A.验收测试 B.系统维护工作 C.项目终验 D.系统试运行 【例2-17上】信息系统集成项目完成验收后要进行一个综合性的项目后评估,评估的内容一般包括&#…

探索Spring中的属性注入:@Value注解解析与应用

探索Spring中的属性注入&#xff1a;Value注解解析与应用 探索Spring中的属性注入&#xff1a;Value注解解析与应用摘要引言正文作用代码准备示例注入字符串注入属性注入Bean及其属性 其他属性注入优先级问题对Value属性注入的扩展Spring Boot对Value类型转换的扩展 代码案例演…

第三门课:结构化机器学习项目-机器学习策略

文章目录 1 机器学习策略一1.1 为什么是ML策略&#xff1f;1.2 正交化1.3 单一数字评估指标1.4 满足和优化指标1.5 训练、开发及测试集划分1.6 开发集和测试集的大小1.7 什么时候改变开发、测试集和指标&#xff1f;1.8 为什么是人的表现&#xff1f;1.9 可避免偏差1.10 理解人…

Unity UGUI之Toggle基本了解

在Unity中&#xff0c;Toggle一般用于两种状态之间的切换&#xff0c;通常用于开关或复选框等功能。 它的基本属性如图&#xff1a; 其中&#xff0c; Interactable&#xff08;可交互&#xff09;&#xff1a;指示Toggle是否可以与用户交互。设置为false时&#xff0c;禁用To…

在Linux系统中如何查询日志?

在工作中&#xff0c;我们有时候会定位问题&#xff0c;这时候就需要查询日志了&#xff0c;那么查询日志的命令有哪些呢&#xff1f; cat 查看某个日志文件中的所有内容。 使用示例&#xff1a;cat file.txt 显示 file.txt 文件的所有内容。 如果要对查询的结果进行筛选&am…

17双体系Java学习之数组的长度

数组的长度 //获取数组长度 arrays.lengthfor (int i 0; i <nums.length; i) {sum sum nums[i];}System.out.println("总和为&#xff1b;"sum);

免费阅读篇 | 芒果YOLOv8改进110:注意力机制GAM:用于保留信息以增强渠道空间互动

&#x1f4a1;&#x1f680;&#x1f680;&#x1f680;本博客 改进源代码改进 适用于 YOLOv8 按步骤操作运行改进后的代码即可 该专栏完整目录链接&#xff1a; 芒果YOLOv8深度改进教程 该篇博客为免费阅读内容&#xff0c;直接改进即可&#x1f680;&#x1f680;&#x1f…

Java八股文(XXL-JOB)

Java八股文のXXL-JOB XXL-JOB XXL-JOB xxl-job 是什么&#xff1f;它的主要作用是什么&#xff1f; xxl-job 是一款分布式任务调度平台&#xff0c;用于解决分布式系统中的定时任务和异步任务调度问题。 它提供了任务的注册、调度、执行和监控等功能&#xff0c;能够帮助开发者…

MindGraph:文字生成知识图

欢迎来到MindGraph&#xff0c;这是一个概念验证、开源的、以API为先的基于图形的项目&#xff0c;旨在通过自然语言的交互&#xff08;输入和输出&#xff09;来构建和定制CRM解决方案。该原型旨在便于集成和扩展。以下是关于X的公告&#xff0c;提供更多背景信息。开始之前&a…