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

代码:

  1. inline void Next(const char a[],int next[],int l){//a为字符串,l为字符串长度 ,next为前缀的最大相同前后缀长度
  2. for(int i=,k=;i<l;i++){//i表示当前计算到第i个前缀,k表示上一个最大相同前后缀长度
  3. while(k>&&a[i]!=a[k]){//上一个最大相同前后缀长度>0并且不相等
  4. k=next[k-];
  5. }
  6. if(a[i]==a[k])k++;//相等就为上一个最大相同前后缀长度+1,不相等就是0;
  7. next[i]=k;
  8. }
  9. }

KMP算法代码

  1. inline void kmp(const char a[],const char b[],int next[],int l1,int l2){//a为文章,b为要查找的串,l1是a的长度,l2是b的长度
  2. for(int i=,q=;i<l1;i++){
  3. while(q>&&b[q]!=a[i])q=next[q-];//如果不相等,则b后移到第一个仍然能匹配成功位置(相当于b串的比较位置前移到next[q-1]+1,这里因为是从0开始所以比较位置前移到next[q-1])
  4. if(b[q]==a[i])q++;//相等就向后比较
  5. if(q==l2){//成功匹配
  6. v[i]=;//i为成功匹配的a末尾的位置,可以进行其他操作
  7. }
  8. }
  9. }

图片来源: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. Markdown语法--整理

    Markdown基本语法 [TOC] 优点: 1.因为是纯文本,所以只要支持Markdown的地方都能获得一样的编辑效果,可以让作者摆脱排版的困扰,专心写作. 2.操作简单.比如:word编辑时标记个 ...

  2. bzoj1433 假期的宿舍

    题意:给你一些人可以睡某某人的床,问是否有所有人都睡下的方案?n<=50. 二分图最大匹配. 用邻接矩阵比较舒服. 标程: #include<cstdio> #include< ...

  3. JavaWeb开发购物车设计总结

    一. 实体类设计 图书实体类 public class Book { private String id; private String name; private String author; pr ...

  4. ODOO/OPENERP的网页模块QWEB简述

    1.web 模块 注意,OpenERP 模块中 web 部分用到的所有文件必须被放置在模块内的 static 文件夹里.这是强制性的,出于安全考虑. 事实上,我们创建的文件夹 CSS,JS 和 XML ...

  5. flask请求上下文源码分析

    一.什么是上下文 每一段程序都有很多外部变量,只有像add这种简单的函数才是没有外部变量的,一旦你的一段程序有了外部变量,这段程序就不完整了,不能独立运行,你为了使他们能运行,就要给所有的外部变量一个 ...

  6. IOS学习笔记57--IOS7状态栏适配(二)

    上一遍文章通过XIB的设置达到了状态栏和view重合的问题,这一篇我们讲一讲网传的修改window frame方法. 先上步骤: 第一:在appdeletage里面 添加如下代码:      if ( ...

  7. hibernate hql语句 注意事项

    现在有实体类 Student 和User . public class Student{ private String id; private Sting classRoom; private Use ...

  8. 04_jQuery对象初识(三)

    <div id="d1"> <p><span>span</span></p> <div>div</di ...

  9. OSG在VS2008下的配置安装

    一.准备工作 下载相关的工具软件: 1, 最新版的OSG库:OpenSceneGraph-2.8.2.zip. 2, 安装源代码所需要的工具:cmake-2.6.4-win32-x86.zip 3,  ...

  10. Codeforces 938G 线段树分治 线性基 可撤销并查集

    Codeforces 938G Shortest Path Queries 一张连通图,三种操作 1.给x和y之间加上边权为d的边,保证不会产生重边 2.删除x和y之间的边,保证此边之前存在 3.询问 ...