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算法的更多相关文章

  1. 字符串匹配算法之 kmp算法 (python版)

    字符串匹配算法之 kmp算法 (python版) 1.什么是KMP算法 KMP是三位大牛:D.E.Knuth.J.H.MorriT和V.R.Pratt同时发现的.其中第一位就是<计算机程序设计艺 ...

  2. 动画演示Sunday字符串匹配算法——比KMP算法快七倍!极易理解!

    前言 上一篇我用动画的方式向大家详细说明了KMP算法(没看过的同学可以回去看看). 这次我依旧采用动画的方式向大家介绍另一个你用一次就会爱上的字符串匹配算法:Sunday算法,希望能收获你的点赞关注收 ...

  3. 字符串匹配算法之————KMP算法

    上一篇中讲到暴力法字符串匹配算法,但是暴力法明显存在这样一个问题:一次只移动一个字符.但实际上,针对不同的匹配情况,每次移动的间隔可以更大,没有必要每次只是移动一位: 关于KMP算法的描述,推荐一篇博 ...

  4. 字符串匹配算法(三)-KMP算法

    今天我们来聊一下字符串匹配算法里最著名的算法-KMP算法,KMP算法的全称是 Knuth Morris Pratt 算法,是根据三位作者(D.E.Knuth,J.H.Morris 和 V.R.Prat ...

  5. Python 细聊从暴力(BF)字符串匹配算法到 KMP 算法之间的精妙变化

    1. 字符串匹配算法 所谓字符串匹配算法,简单地说就是在一个目标字符串中查找是否存在另一个模式字符串.如在字符串 "ABCDEFG" 中查找是否存在 "EF" ...

  6. 数据结构学习之字符串匹配算法(BF||KMP)

    数据结构学习之字符串匹配算法(BF||KMP) 0x1 实验目的 ​ 通过实验深入了解字符串常用的匹配算法(BF暴力匹配.KMP.优化KMP算法)思想. 0x2 实验要求 ​ 编写出BF暴力匹配.KM ...

  7. 字符串匹配算法之Sunday算法(转)

    字符串匹配算法之Sunday算法 背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是Ω(m*n),也就是达到了字符串匹配效率的下限.于是后来人经过研究 ...

  8. 字符串匹配算法之BM算法

    BM算法,全称是Boyer-Moore算法,1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹配算法. BM算法定义了两个规则: ...

  9. 数据结构4_java---顺序串,字符串匹配算法(BF算法,KMP算法)

    1.顺序串 实现的操作有: 构造串 判断空串 返回串的长度 返回位序号为i的字符 将串的长度扩充为newCapacity 返回从begin到end-1的子串 在第i个字符之前插入字串str 删除子串 ...

随机推荐

  1. <linux常用命令>初级版

    显示时间 date 显示日历cal 变换目录 cd 显示当前所在目录 pwd 建立新目录 mkdir -p a/b/c 删除空目录 rmdir 当前目录下文件和目录显示 ls 复制 cp 文件 路径 ...

  2. P1006 传纸条 /// DP+滚动数组

    题目大意: https://www.luogu.org/problemnew/show/P1006 题解 不难想到 求从起点到终点的两条不同的路 因为只能向右或向下走 所以纸条1和2不可能同时位于同一 ...

  3. 设置编辑工具UltraEdit的背景色为护眼颜色

    1.视图--->主题--->管理主题---> 2.--->编辑器--->纯文本--->第二个框(背景色) 3.--->规定自定义颜色--->建议(色调: ...

  4. 关于Android 的网址

    Android 官方API查询网址 https://developer.android.google.cn/ 第三方镜像Android API查询网址 (比官方浏览速度快一些,缺点现有API较低) h ...

  5. 【BZOJ4407】于神之怒加强版

    题面 题目分析 \[ \begin{split} \sum\limits_{i=1}^n\sum\limits_{j=1}^mgcd(i,j)^k&=\sum\limits_{d=1}^nd^ ...

  6. jvisualvm图解【转】

    jvisualvm图解[转]   http://blog.csdn.net/a19881029/article/details/8432368 jvisualvm能干什么:监控内存泄露,跟踪垃圾回收, ...

  7. DbUtils要点小结

    一. DbUtils核心API 1. QueryRunner update方法 query方法 2. 各种Handler都实现ResultSetHandler接口 beanhandler beanli ...

  8. StringBuffer清空

    转载自:http://blog.sina.com.cn/s/blog_56fd58ab0100qfcz.html 在开发程序的时候,经常使用StringBuffer来进行字符串的拼接.如果在循环中来反 ...

  9. <scrapy爬虫>爬取校花信息及图片

    1.创建scrapy项目 dos窗口输入: scrapy startproject xiaohuar cd xiaohuar 2.编写item.py文件(相当于编写模板,需要爬取的数据在这里定义) # ...

  10. 11-4-while和dowhile

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...