详解KMP字符串匹配算法

[数据结构]模式匹配算法--KMP算法详解 KMP 阅读详情

字符串匹配

字符串匹配一般是指在较长的一个字符串A中查找是否含有较短字符串B、B在A中的位置的过程。最容易想到、也是最长用的一种办法是暴力匹配。String.contains() 用的就是这种方法,应该说这种简单的方法用的还是特广泛的。

KMP算法

KMP算法俗称“看毛片”算法,通过计算next[] 数组的方法加速匹配过程。

next[] 数组:

首先要明白几个概念,字符串中的字符的前置字符串(如果有),后置字符串。很容易理解,前置字符串就是这个字符前面的一段字符串、后置字符串就是这个字符后面的一串字符串。
前后置字符串

next[i] 数组的定义,它反映的是i位置上的字符串,它的前置字符串的最长相同的前缀和后缀字符串的长度。前置字符串应该不陌生,上面图像中 “abcdksid” 就是字符“g”的前置字符串,最长相同前缀和后缀字符串的长度,因为“abcdksid”没有相同的前缀和后缀,所有g处next[]的值为0。例如,“abcdabc”,为3,“abcdefa”,为1。

next[i]数组的计算。它是通过遍历该字符串的每个位置,算出每个位置处的值。第0个字符因为没有前缀字符串,定义next[0]=-1; 第1个字符因为其前缀字符串只有一个字符,next数组的定义要求任何子串的后缀不能包括第一个字符,也就是说没有所谓的相同的前缀字符串和后缀字符串,该处的值也定义为0,next[1]=0。后续next[i]值的计算,是根据前面位置处next[0] – next[i-1]的值计算出来的,如果str[i-1]==str[next[i-1]],则next[i]=next[i-1]+1。否则,比较str[i-1]与str[next[next[i-1]]]。形象说明可以参考下图:
计算next数组

具体代码如下:

public static int[] getNextArray(char[] ms){
		if(ms.length==1){
			return new int[] {-1};
		}
		int[] next=new int[ms.length];
		next[0]=-1;
		next[1]=0;
		int pos=2;
		int cn=0;
		while(pos<next.length){
			if(ms[pos-1]==ms[cn]){
				next[pos++]=++cn;
			}else if(cn>0){
				cn=next[cn];
			}else{
				next[pos++]=0;
			}
		}
		return next;
	}

这里cn一直指向可能最长相同字符串的最后一个字母。左老师这段代码相当精髓。

KMP遍历方法:

求出next数组之后,就可以根据next数组的值,在待匹配字符串上进行快速匹配。和暴力字符串匹配方法(String.contains()就是用的暴力匹配)类似,只不过运用到了next数组的值,跳过了一些匹配环节。这里最关键的一个问题是,为什么在跳过的那部分匹配中不可能找到相匹配的字符串。具体证明可以用下面的图说明,证明运用了反证法(有很多问题正面证明有困难的时候,往往反证法就会比较有用了)。
为什么跳过next
上图是一次匹配过程,目的是在上面字符串中找到下面字符串所在的位置(如果有的话),第一次匹配的时候,在A,B处发现匹配失败,也就是说A、B前面的字符串都是相同的。KMP算法会直接向右移动A处next值的长度进行下一次匹配,现在来证明这个的合理性。假设向右移动x字符串长度的位置(小于A处next值),根据上图的推理得出矛盾。

具体代码如下:

public int getIndexOf(String s,String m){
		if(s==null || m==null || m.length()<1 || s.length()<m.length()){
			return -1;
		}
		char[] ss=s.toCharArray();
		char[] ms=m.toCharArray();
		int si=0;
		int mi=0;
		int[] next=getNextArray(ms);
		while(si<ss.length&&mi<ms.length){
			if(ss[si]==ms[mi]){
				si++;
				mi++;
			}else if(next[mi]==-1){
				si++;
			}else{
				mi=next[mi];
			}
		}
		return mi==ms.length? si-mi:-1;
	}

(特别感谢 左程云 老师,他讲的算法特别透彻)

KMP算法详解-彻底清楚了(转载+部分原创) KMP算法详解-彻底清楚了(转载+部分原创) 引言 KMP算法指的是字符串模式匹配算法,问题是:在主串T中找到第一次出现完整子串P时的起始位置。该算法是三位大牛:D.E.Knuth、J.H.Morris和V.R.Pratt同时发现的,以其名字首字母命名。在网上看了不少对KMP算法的解析,大多写的不甚明了。直到我看到一篇博客的介绍,看完基本了解... 阅读详情

相关推荐

字符串匹配算法之KMP算法(图例详解)

字符串匹配算法之KMP算法(图例详解)

Sueko的博客 4187

KMP算法详解

字符串匹配是计算机的基本任务之一。举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"?下面列举匹配过程: 1. 首先,字符串"BBC ABCDAB ABCDABCDABDE"的第一个字符与搜索词"ABCDABD"的第一个字符,进行比较。因为B与A不匹配,所以搜索词后移一位。 2

ZCC的专栏 1323

字符串匹配KMP算法详解

1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有比较详细的通俗易懂的讲解,另一方面也怪自己没有沉下心来研究。最近在leetcode上又遇见字符串匹配的题目,以此为契机,好好总结一下KMP算法。有何疑问,欢迎评论交流。   2. 暴力匹配算法(传统算法) 假设现在有这样一个问题:有一个文本串S,和一个模式串P,现在要判断S中是否有和P匹

追梦boy的博客 576

KMP模式匹配算法

KMP模式匹配算法的分析介绍

daye_的博客 3348

Matlab实战:用递归最小二乘法(RLS)搞定动态系统参数辨识(附完整代码)

本文通过Matlab实战,详细介绍了如何利用递归最小二乘法(RLS)进行动态系统参数辨识。文章从理论优势切入,提供了完整的仿真数据生成、RLS算法核心实现代码,并对参数收敛过程、预测误差及不同遗忘因子的影响进行了可视化分析与性能评估,为工程实践提供了清晰的指南。

weixin_29035405的博客 503

jaka+realsense+aruco+手眼标定(python)

第二次重建了项目的手眼标定部分……有很多第一次记录遗漏的地方,在此补充。

drivenzyw的博客 2122

串的匹配,详解KMP算法及NEXT数组(C/C++)

完全详细介绍了串的匹配的前世今生

tyq20010606的博客 3026

机器学习项目(四)疫情期间网民情绪识别 (一)

疫情期间网民情绪识别 赛题背景 2019新型冠状病毒(2019-nCoV)感染的肺炎疫情发生对人们生活生产的方方面面产生了重要影响,并引发国内舆论的广泛关注,众多网民参与疫情相关话题的讨论。为了帮助政府掌握真实社会舆论情况,科学高效地做好防控宣传和舆情引导工作,本赛题针对疫情相关话题开展网民情绪识别的任务。 数据介绍 训练集 10万条 无标记样本90万条 测试集1万条 数据集依据与“新冠肺炎”相关...

qq_33357094的博客 8971

字符串匹配算法KMP详解

本人是普通本科院校的一名大二学生,为提高自身能力特地锻炼自己发表一些文章,题解等, 望各位大佬能够对我这个菜鸟所做多多指正,在此谢过各位啦~~~ 文章的开始,我想向KMP算法的三位创始人Knuth,Morris,Pratt致敬,如此思维之精妙,堪称大神。 KMP算法是字符串匹配算法中一个很重要的算法,KMP算法的作用是在一个字符串中寻找子串的位置,也叫串的模式匹配。如主串s="aaabbaab",子串t(也叫模板串)="aab",要寻找aab在主串中的位置。 字符串匹配的暴力做法就是分别将两个指针i,

qq_51502732的博客 4659

AMDGPU IH(Interrupt Handler)实现分析

AMDGPU IH环形缓冲区机制是显卡驱动中高效处理GPU硬件中断的核心架构。该机制通过环形缓冲区存储中断事件,利用读写指针(wptr/rptr)同步硬件与驱动间的数据交互。硬件写入事件后驱动遍历处理,通过指针掩码实现环形循环,并具备溢出检测和虚拟化环境下的重置保护。其优势在于批量处理降低中断开销,指针同步确保可靠性,支持多队列扩展和SR-IOV虚拟化场景,为GPU中断管理提供了高性能基础架构。

图形/计算GPU的驱动与虚拟化技术分享园地 1639

基于 ESP32 与 TDS 传感器的水培营养液离子浓度自动配比系统设计与实现

本系统以 ESP32 为主控芯片,结合 TDS(总溶解固体)传感器实时监测水培营养液中的离子浓度,通过蠕动泵自动补充浓缩营养液或清水,实现营养液 EC 值的闭环自动配比。系统适用于家庭及小型农场的水培种植场景,可稳定维持营养液浓度在作物生长所需的最佳区间。

weixin_42300449的博客 80

KMP算法详解 - 字符串匹配的艺术

KMP算法通过。

hongjianMa的博客 1027

十五、SAP-物料需求计划(MRP)

业务逻辑、功能讲解、图文解析、章节总结

m0_72403327的博客 1093

KMP字符串匹配算法详解

  KMP算法利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。 Next()函数的详解 把将要进行next计算的字符串S分成 k ,j 前后两串,k代表前串开头所在的序号,j代表后串开头所在的序号,起始的时候j=1,k=0。 我们比较一下前串 后串是否相等...

dielu7895的博客 279

STM32开发 -- GPS模块开发详解

一、了解硬件 我使用的GPS模块型号为UBX-M8030 参看:UBX-M8030 系列 查看一下它的特性: 多用途 GNSS 芯片,提供三种产品等级 最多可并发接收 3 个 GNSS(GPS、伽利略、GLONASS、北斗) 行业领先的 -167 dBm 导航灵敏度 业界最低电流消耗 在城市峡谷中具有绝佳的定位精度 安全性和完整性保护 支持所有的卫星增强系统 车载级芯片的工作...

不积跬步,无以至千里 3万+

基于STM32的太阳能充电宝设计_资料编号31

系统硬件包括主控 STM32F103C8T6、0.96 OLED 显示屏、蜂鸣器、电源自锁开关、温度传感器 DS18B20、继电器、5 V DC 升压模块 、TB4056、18650锂电池、9 V太阳能板、稳压降压 5 V三极管。电源供应:锂电池为系统供电,9 伏太阳能板经 5 伏降压稳压三极管降压为 5 伏后传送到 TP4056,TP4056 为锂电池供电,因锂电池电压 3.7 伏,通过 5 伏 DC 升压模块升压到 5 伏为整个系统提供 5 伏电压。

嵌入式阿齐Archie 1万+

KMP 字符串匹配算法详解

KMP(Knuth-Morris-Pratt)算法是一种高效的字符串匹配算法,用于在主串中查找模式串是否出现过,其核心思想是通过构建部分匹配表(也称为前缀函数表或 next 数组)来避免主串指针的重复回溯。- 若失配,模式串根据 next 表移动,而主串指针不回溯。从主串位置 6 重新开始匹配,最终匹配成功,起始位置为 5。- 若当前字符匹配,则主串和模式串指针均后移。3. 当模式串完全匹配时,返回主串中匹配的起始位置。匹配到第5位时,主串为 e,模式串为 c,失配。模式串:abcabcmn。

qq_43191011的博客 524

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

[C++]洛谷:KMP字符串匹配 KMP算法详解

洛谷:KMP字符串匹配详解,简单易懂

weixin_62712365的博客 1343

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

字符串匹配算法-KMP详解

这两天在看字符串匹配算法,第一次看到KMP算法的时候觉得很难。于是上网搜分析,网上讲KMP的算法很多,只是好像很多都讲的云里雾里的,不甚清晰。后来想想还是找教材看看,第一回看的是《算法》第四版,其实没看懂;于是再找来CLRS看,恍然大悟,果然还是CLRS大法好。本文主要是梳理一下整个思路,尽自己所能讲得尽量清晰易懂。 首先先从什么是字符串匹配开始:字符串匹配就是给定一个字符串S,然后在另一个字符

Swartz2015的专栏 847

字符串匹配的KMP算法--前缀和后缀的详解

字符串匹配的KMP算法 作者: 阮一峰 字符串匹配是计算机的基本任务之一。 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"? 许多算法可以完成这个任务,Knuth-Morris-Pratt算法(简称KMP)是最常用的之一。它以三个发明者命名,起头的

Wait for 的专栏 3万+

字符串匹配KMP算法详解。

一、什么是KMP算法    首先说说什么是KMP算法,说白了,就是不希望用简单的两层循环遍历两个串那样去看能否匹配成功。简单朴素的字符串匹配是,一旦匹配不成功,主串要回到匹配开始的起始位置,然后加1再和模式串从头匹配。二、 字符串匹配算法的实现思路(A暴力匹配和B通过next数组KMP算法实现)主串:s='ababbabababbbab';子串:p='abababbbab';A :暴力匹配实现。 ...

zlb_lover的博客 457

算法【字符串匹配】| KMP算法详解

文章目录一、简介二、图解三、代码 一、简介 Knuth-Morris-Pratt字符串搜索算法(或KMP 算法)通过观察在发生不匹配时,单词本身包含足够的信息来搜索W主要“文本字符串”中出现的“单词”S来确定下 一个匹配的开始位置,从而绕过对先前匹配字符的重新检查。 该算法由James H. Morris构思,并由Donald Knuth “几周后”从自动机理论中独立发现。Morris 和Vaughan Pratt在 1970 年发表了技术报告。 三人也在 1977 年联合发表了该算法。独立地,1969 年

weixin_45926547的博客 873

字符串匹配算法KMP原理详解及C++实现

问题介绍 KMP算法是用来解决字符串匹配算法的。例如给定一个主串T,判断其中是否出现了模式串P,即P是否为T的子串。例如:主串T为“hello”,模式串P为“el”,那么P就是T的子串;若模式串P为“elo”,那么P就不是T的子串。 暴力法解决字符串匹配 思路很简单。从主串的首字符开始匹配,如果匹配失败,则从主串的第2个字符开始匹配,以此类推。由于思路简单,直接上代码。 ...

bqw的博客 4482
上一篇: 通配符、通配符上限、通配符下限
下一篇: 如何查看Java对象占用JVM内存大小
wangdaowei90
博客等级 码龄17年 7粉丝 29原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值