字符串匹配算法——KMP

有文本串aabaabaaf,模式串aabaaf问文本串中是否出现过模式串

暴力解法

最不用动脑子的,直接两层for循环,逐个匹配,匹配到不相等的值时把文本串后移一位,再重新比较。这种方法的复杂度是O(m×n),该方法低效的原因在于重复比较次数过多,比如当比较到aabaa时发现此时的fb不相符,又从头开始比较,但ff和b前有相同的aa,如果我们能直接从b开始比较是不是高效多了呢?由此产生了KMP算法。

KMP算法概述

KMP算法就是当模式串与文本串字符不等时,不移动至头部进行比较,比如fb不匹配,跳至b进行比较,节约了前面相同aa的比较次数,尝试将比较过程直观展示如下:
逐个比较到f发现不匹配

a	a	b	a	a	b	a	a	f
|	|	|	|	|	!=
a	a	b	a	a	f

此时再从之前已知匹配的aa后面的b开始比较即可

a	a	b	a	a	b	a	a	f
 	 	 	 |	|	|	|	|	|
 	 	 	 a	a	b	a	a	f

那我们如何得知之前匹配的内容呢?这时就要引入前缀表的概念。

前缀表

a	a	b	a	a	f
0	1	0	1	2	0

形如上表这样,比较到当前字符发现不匹配时,可由前一位对应的字符找到此时应跳转的位置,这样的表为前缀表,具体如何找到对应字符应跳转的位置,要先引入前后缀的概念。
前缀为包含首字母,不包含尾字母的所有字串;后缀为包含尾字母,不包含首字母的所有字串,以该模式串为例,其所有前缀和后缀为:

前缀:a	aa	aab	aaba	aabaa
后缀:f	af	aaf	baaf	abaaf

模式串不同字串对应的最长相等前后缀表格如下:

a		aa		aab		aaba	aabaa	aabaaf
0		1		0		1		2		0
a		a		b		a		a		f

当不匹配时找前一个字符最长相等前后缀即可,在编程中我们将其命名为next数组。

next数组代码示例

a	a	b	a	a	f
j	i	
0
void getNext(next,s)//s为模式串{	
	j=0;next[0]=0;//初始化,i,j表示后前缀末尾指向位置
	for(i=1;i<s.size();i++){//后缀指向1,第一个字符无后缀,故其最长相等前后缀为0
			while(j>0&&s[i]!=s[j])//当前后缀不等时,j等于前一个字符对应的next数组位置
			j=next[j-1];
		if(s[i]==s[j]//前后缀相等时,j后移一位,i的后移在循环中实现
			j++;
		next[i]=j;}保存next数组
	}
}			

该代码实现了next数组即解决了如果当下不满足时该从何处比较的问题,也就是求出不同字符串下最长相等前后缀,方式是比较前后缀的最后一位来判定,那我想比较前后缀相同不是还要通过两个for循环来实现吗,为什么比较前后缀的最后一位就能判定两个不同的字符串最大相等前后缀长度呢?
当前后缀相等时我们很好理解,因为前面的相等已经判断过了,所以如果当下判定位置仍相等时,只需在上一次结果上+1即可;主要是当下判定位置不等时如何理解,执行步骤是向前遍历,直至找到与后缀字符相等的字符,并将前缀末尾指向之,想了半天又看了几遍实在不明白咋回事,贴两张图看看能不能理解吧,好像用到了动态规划的思想?前后缀匹配
前后缀不匹配

总结

KMP算法是用于比较字符串的一种高效算法,特点在于字符串只向前,模式串节约了重复部分的比较次数,实现通过next数组,但涉及next数组的求解人家有很巧妙的办法,五行代码就给搞定了,比我手算还简单,没有明白,暂时就到此为止吧。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java--static的应用知识:单例设计模式

1.什么是设计模式(Design pattern) ①一个问题通常有n中解法&#xff0c;其中肯定有一种解法最优的&#xff0c;这个最优的解法被人总结出来了&#xff0c;称之为设计模式。 ②设计模式有20多种&#xff0c;对应20多种软件开发中会遇到的问题。 2.单例设计模式 确保一个类只…

【史上最细教程】服务器MySQL数据库完成主从复制

文章目录 MySQL完成主从复制教程准备&#xff1a;原理&#xff1a;步骤&#xff1a; 推荐文章 MySQL完成主从复制教程 主从复制&#xff08;也称 AB 复制&#xff09;就是将一个服务器&#xff08;主服务器&#xff09;的数据复制到一个或多个MySQL数据库服务器&#xff08;从…

windows根据已有的安卓签名文件获取MD5签名

windows根据已有的安卓签名文件获取MD5签名 0 现状 uniapp 本机号码一键登录需要MD5的&#xff0c;现有的签名文件但是只有SHA1和SHA256 查看SHA1和SHA256 keytool -list -v -keystore [你的.keystore文件]1 前提 已有生成签名文件的环境 搭建Openssl环境&#xff0c;设置…

Spring框架学习 -- 读取和存储Bean对象

目录 &#x1f680;&#x1f680; 回顾 getBean()方法的使用 根据name来获取对象 再谈getBean() (1) 配置扫描路径 (2) 添加注解 ① spring注解简介 ② 对类注解的使用 ③ 注解Bean对象的命名问题 ④ 方法加Bean注解 (3) Bean 注解的重命名 (4) 获取Bean对象 -- …

Linux---常用命令汇总

文章目录 关于目录操作的命令ls/llcdpwdmkdir 关于文件操作的命令touchechocatrmmvcpvim 关于查询操作的命令greppsnetstat 关于目录操作的命令 ls/ll ls : 列出当前目录下的目录和文件&#xff08;以行的展示形式&#xff09; ll &#xff1a; 列出当前目录下的目录和文件&…

如何正确接入API接口通过淘宝商品ID和sku ID获取到淘宝商品SKU信息接口,可获取sku价格,sku销量,sku图片及sku库存参数等

接入API接口的正确方式可能因API的具体要求而有所不同&#xff0c;但一般来说&#xff0c;以下是一些通用的步骤&#xff1a; 获取API文档&#xff1a;API文档通常包括API的请求方式、请求参数、响应格式等信息。您需要仔细阅读文档&#xff0c;了解API的具体要求和使用方式。…

构建个性化预约服务:预约上门服务系统源码解读与实战

随着社会的发展&#xff0c;预约上门服务系统在满足用户需求、提升服务效率方面发挥着越来越重要的作用。在本文中&#xff0c;我们将深入研究预约上门服务系统的源码&#xff0c;通过实际的技术代码示例&#xff0c;揭示系统内部的关键机制&#xff0c;以及如何在实际项目中应…

mybatis 语法使用各种踩坑(持续更新中。。。)

1、大小写命名&#xff1a;这个别说了&#xff0c;都是泪。 2、联表查询查询&#xff0c;多条合成一条&#xff0c;不生效的原因 博主各种检查关联关系和字段大小写&#xff0c;本来是4条数据最后合成一条数据&#xff0c;死活给你直接返回了4条数据&#xff0c;而且每个类似p…

四肽-3——增加皮肤光滑度、紧致度,让肌肤看起来更年轻

Caprooyl四肽-3&#xff0c;也称为KGHK Caproic acid&#xff0c;是一种基于TGF-&#xff08;转化生长因子β&#xff09;的仿生脂肽结构&#xff0c;在细胞外基质成分的自然产生中发挥重要作用。肽序列是Lys-Gly-His-Lys。它可以减少细纹和皱纹的出现&#xff0c;提高皮肤弹性…

万宾科技智能井盖传感器效果,特点有哪些?

现在城市发展越来越好&#xff0c;对基础设施的改造越来越多&#xff0c;比如修路搭桥、整改生态等都是为民服务的好工程。平时走在路上我们享受着平整的路面&#xff0c;井然有序的交通也为我们带来很大的方便。但是一个又一个的井盖看起来无关紧要&#xff0c;实际上如果路上…

shell循环语句 for while until

目录 什么是循环语句 概念 for循环 格式 while循环 格式 until 循环 格式 实验 for &#xff08;1&#xff09;计算1到100的和 ​编辑 &#xff08;2&#xff09;100以内的偶数 &#xff08;从0开始到100结束&#xff0c;每次加2步 打印的都是偶数&#xff09; &…

maxwell采集数据到kafka报错

问题&#xff1a; 启动maxwell后出现数据更新后就出现以下报错。 13:29:14,727 ERROR MaxwellKafkaProducer - TimeoutException Position[BinlogPosition[binlog.000002:12215591], lastHeartbeat1700717043797] -- maxWellData: medical:consultation:[(id,212)] 13:29:14,7…

DNS协议、ICMP协议、NAT技术

文章目录 一.DNS协议1.DNS背景2.域名简介3.域名解析过程4.使用dig工具分析DNS过程 二.ICMP协议1.ICMP功能2.ICMP协议格式3.ping命令4.一个值得注意的坑5.traceroute命令 三.NAT技术1.NAT技术背景2.NAT IP转换过程3.NAPT4.NAT技术的缺陷5.NAT和代理服务器 四.网络协议总结1.应用…

微信运营神器:从群发到批量添加,让你的微信营销更轻松

在这个数字化时代&#xff0c;微信已经成为了我们生活中不可或缺的一部分。对于许多企业和个人来说&#xff0c;微信营销也是非常重要的一部分。但是&#xff0c;微信营销并不是一件容易的事情&#xff0c;需要花费大量的时间和精力。为了解决这个问题&#xff0c;今天我们将向…

C语言——接受一个整形值(无符号),使用函数的递归,按照顺序打印他的每一位。

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>void print(int n) {if(n>9){print(n/10);}printf("%d ",n%10); }int main() {unsigned int num 0;scanf("%d", &num);print(num);return 0; }

JavaScript 如何拷贝对像(Object)或者数组(Array)

目录 JavaScript数据拷贝类型 浅拷贝 深拷贝 举例&#xff1a; 浅拷贝 数组 对象 深拷贝 lodash cloneDeep使用示例 自定义深拷贝方法示例 JSON.parse() 和 JSON.stringify()使用示例 JavaScript数据拷贝类型 浅拷贝 数组可以使用Array.prototype.slice()方法 …

高通Camera HAL3: CamX、Chi-CDK要点

目录 一、概述 二、目录 三、CamX组件之前的关系 一、概述 高通CamX架构是高通实现的相机HAL3架构&#xff0c;被各OEM厂商广泛采用。 二、目录 代码位于vendor/qcom/proprietary下&#xff1a; camx&#xff1a;通用功能性接口的代码实现集合chi-cdk&#xff1a;可定制化…

排查光模块故障原因,少不了这2条命令!

光模块故障定位常用命令 根据光模块的告警信息查找故障原因&#xff1a; display interface transceiver查看光模块光功率是否正常 display interface transceiver verbose根据光模块的告警信息查找故障原因 执行命令display interface transceiver查看“Alarm information”…

【鸿蒙应用ArkTS开发系列】- 云开发入门实战二 实现省市地区联动地址选择器组件(上)

目录 概述 云数据库开发 一、创建云数据库的对象类型。 二、预置数据&#xff08;为对象类型添加数据条目&#xff09;。 三、部署云数据库 云函数实现业务逻辑 一、创建云函数 二、云函数目录讲解 三、创建resources目录 四、获取云端凭据 五、导出之前创建的元数据…

redis之cluster集群

1、redis-cluster集群&#xff1a;redis3.0引入的分布式存储方案 2、集群&#xff1a;由多个node节点组成&#xff0c;redis数据分布在这些节点之中 &#xff08;1&#xff09;在集群之中也分主节点和从节点 &#xff08;2&#xff09;自带哨兵模式 3、redis-cluster集群的…