字符串匹配算法之kmp算法
kmp算法是一种效率非常高的字符串匹配算法,是由Knuth,Morris,Pratt共同提出的模式匹配算法,所以简称KMP算法
算法思想
在一个字符串中查找另一个字符串时,会遇到如下图的情况

我们通常的做法是从第一个串A的下一位B再逐位比较,但这样的做法非常低效。
仔细思考一下发现,第一个串已经匹配的部分就是第二个串的前缀。如果我们对第二个串进行一些预处理,或许就不用再去逐位比较了。
KMP算法就是预处理出要查找串每个前缀的最大相同前后缀的长度,通俗一点就是两个相同的串在不重合情况下最大的重叠长度
如上图中ABCDAB前缀的最大相同前后缀就是AB,长度为2

这样我们在D匹配不成功时,就可以直接将查找串后移到第一个仍然能匹配成功位置(要找的串的比较位置前移到最大相同前后缀中前缀的下一个位置),如下图:最大相同前后缀为AB,移到下一个位置C

如果还匹配不成功,则继续将查找串后移到第一个仍然能匹配成功位置,发现没有,就从头比较

这时从头比较也不成功,就将两个的比较位置都后移
总结:
- 如果两个串比较位置相等,则向后比较
- 如果不相等,则将要找的串后移到第一个仍然能匹配成功的位置(要找的串的比较位置前移到最大相同前后缀中前缀的下一个位置)
求最大相同前后缀(用next数组存储)

对于上图的字符串,它的前三个前缀没有最大相同前后缀
第四个前缀ABDA,因为第一个字符和最后一个字符相同,所以它的最大相同前后缀为1
第五个前缀,只需比较第四个前缀最大相同前后缀的后一个字符和最后一个字符(第一个B和第二个B)就行了,
如果相等,则第五个前缀最大相同前后缀长度=第四个前缀最大相同前后缀长度+1,并且一定是最大的
重点:如果最后一个字符与前一个前缀的最大相同前后缀的后一个字符不相等
考虑
的最大相同前后缀
前一个前缀
的最大相同前后缀是
但最后一个字符D不等于最大相同前后缀的下一个字符C
这时字符串的最大相同前后缀一定小于5了,并且ABDAB已经匹配成功
我们就要再找后缀ABDAB的一个后缀与前缀ABDAB的一个前缀进行匹配,
这就是前缀ABDAB的最大相同前后缀AB。
我们比较
的最后一个字符D和前缀
的下一个字符D发现它们相等,则
的最大相同前后缀为ABD。
总结一下
- 如果当前前缀的最后一个字符与上一个最大相同前后缀(上一个前缀的最大相同前后缀,以下简称)的下一个字符相等,则当前前缀的最大相同前后缀长度=上一个最大相同前后缀长度+1
- 如果当前前缀的最后一个字符与上一个最大相同前后缀的下一个字符不相等,则将上一个最大相同前后缀变为它的最大相同前后缀,继续比较,直到相等,或上一个最大相同前后缀变为0
代码:
inline void Next(const char a[],int next[],int l){//a为字符串,l为字符串长度 ,next为前缀的最大相同前后缀长度
for(int i=,k=;i<l;i++){//i表示当前计算到第i个前缀,k表示上一个最大相同前后缀长度
while(k>&&a[i]!=a[k]){//上一个最大相同前后缀长度>0并且不相等
k=next[k-];
}
if(a[i]==a[k])k++;//相等就为上一个最大相同前后缀长度+1,不相等就是0;
next[i]=k;
}
}
KMP算法代码
inline void kmp(const char a[],const char b[],int next[],int l1,int l2){//a为文章,b为要查找的串,l1是a的长度,l2是b的长度
for(int i=,q=;i<l1;i++){
while(q>&&b[q]!=a[i])q=next[q-];//如果不相等,则b后移到第一个仍然能匹配成功位置(相当于b串的比较位置前移到next[q-1]+1,这里因为是从0开始所以比较位置前移到next[q-1])
if(b[q]==a[i])q++;//相等就向后比较
if(q==l2){//成功匹配
v[i]=;//i为成功匹配的a末尾的位置,可以进行其他操作
}
}
}
图片来源:https://www.cnblogs.com/zhangtianq/p/5839909.html
字符串匹配算法之kmp算法的更多相关文章
- 字符串匹配算法之 kmp算法 (python版)
字符串匹配算法之 kmp算法 (python版) 1.什么是KMP算法 KMP是三位大牛:D.E.Knuth.J.H.MorriT和V.R.Pratt同时发现的.其中第一位就是<计算机程序设计艺 ...
- 动画演示Sunday字符串匹配算法——比KMP算法快七倍!极易理解!
前言 上一篇我用动画的方式向大家详细说明了KMP算法(没看过的同学可以回去看看). 这次我依旧采用动画的方式向大家介绍另一个你用一次就会爱上的字符串匹配算法:Sunday算法,希望能收获你的点赞关注收 ...
- 字符串匹配算法之————KMP算法
上一篇中讲到暴力法字符串匹配算法,但是暴力法明显存在这样一个问题:一次只移动一个字符.但实际上,针对不同的匹配情况,每次移动的间隔可以更大,没有必要每次只是移动一位: 关于KMP算法的描述,推荐一篇博 ...
- 字符串匹配算法(三)-KMP算法
今天我们来聊一下字符串匹配算法里最著名的算法-KMP算法,KMP算法的全称是 Knuth Morris Pratt 算法,是根据三位作者(D.E.Knuth,J.H.Morris 和 V.R.Prat ...
- Python 细聊从暴力(BF)字符串匹配算法到 KMP 算法之间的精妙变化
1. 字符串匹配算法 所谓字符串匹配算法,简单地说就是在一个目标字符串中查找是否存在另一个模式字符串.如在字符串 "ABCDEFG" 中查找是否存在 "EF" ...
- 数据结构学习之字符串匹配算法(BF||KMP)
数据结构学习之字符串匹配算法(BF||KMP) 0x1 实验目的 通过实验深入了解字符串常用的匹配算法(BF暴力匹配.KMP.优化KMP算法)思想. 0x2 实验要求 编写出BF暴力匹配.KM ...
- 字符串匹配算法之Sunday算法(转)
字符串匹配算法之Sunday算法 背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是Ω(m*n),也就是达到了字符串匹配效率的下限.于是后来人经过研究 ...
- 字符串匹配算法之BM算法
BM算法,全称是Boyer-Moore算法,1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹配算法. BM算法定义了两个规则: ...
- 数据结构4_java---顺序串,字符串匹配算法(BF算法,KMP算法)
1.顺序串 实现的操作有: 构造串 判断空串 返回串的长度 返回位序号为i的字符 将串的长度扩充为newCapacity 返回从begin到end-1的子串 在第i个字符之前插入字串str 删除子串 ...
随机推荐
- Spring - 整合MyBatis
目的: 使用 Spring 容器用单例模式管理 MyBatis 的 sqlSessionFactory : 使用 Spring 管理连接池.数据源等: 将 Dao / Mapper 动态代理对象注入到 ...
- 数组,List,Set相互转化
1.数组转化为List: String[] strArray= new String[]{"Tom", "Bob", "Jane"}; Li ...
- Android 开发 MediaRecorder使用Camera1配合录制视频
前言 MediaRecorder可以不依靠Camera API 实现视频的录制,但是如果需要切换摄像头/设置对焦/选择分辨率等等就需要Camera来参与配合录制视频.这篇博客将介绍使用Camera1来 ...
- html-圣杯布局
1.两边固定 当中自适应 2.当中列要完整显示 3.当中列要优先加载 浮动: 搭建完整的布局框架 margin 为赋值:调整旁边两列的位置(使三列布局到一行上) 使用相对定位:调整旁边两列的位置(使两 ...
- Java 生成pdf表格文档
最近在工作做一个泰国的项目,应供应商要求,需要将每天的交易生成pdf格式的报表上传到供应商的服务器,特此记录实现方法.废话不多说,直接上代码: THSarabunNew.ttf该文件是泰国字体自行网上 ...
- 今天给各位介绍Linux touch命令详述
触摸命令 touch命令有两个功能:一个是将现有文件的时间戳更新为系统的当前时间(默认模式),它们的数据将保持不变;第二个是创建一个新的空文件. 语法 触摸(可选) 最常见的用法:touch file ...
- 即将开源 | 2亿用户背后的Flutter应用框架Fish Redux
背景 在闲鱼深度使用 Flutter 开发过程中,我们遇到了业务代码耦合严重,代码可维护性糟糕,如入泥泞.对于闲鱼这样的负责业务场景,我们需要一个统一的应用框架来摆脱当下的开发困境,而这也是 Flut ...
- springboot与热部署
在开发中我们修改一个Java文件后想看到效果不得不重启应用,这导致大量时间花费,我们希望不重启应用的情况下,程序可以自动部署(热部署).有以下四种情况,如何能实现热部署. 1.模板引擎: 在Sprin ...
- windows环境下,svn未备份情况下重新恢复
公司有个同事在未打招呼的情况下把公司服务器进行重新装系统,崩溃啊.SVN之前未备份,还好SVN的库(Repositories)还在,如下图: 恢复办法如下: 由于之前安装的就是VisualSVN-Se ...
- SpringBoot学习笔记(三):SpringBoot集成Mybatis、SpringBoot事务管理、SpringBoot多数据源
SpringBoot集成Mybatis 第一步我们需要在pom.xml里面引入mybatis相关的jar包 <dependency> <groupId>org.mybatis. ...