KMP算法之前看过一次,看了好久才看明白,今天又学的时候发现啥也不会了,又看了好久,在这里整理一下思路,方便以后复习。

算法介绍

在我们常规的模式匹配算法中,每当匹配失败时,模式串都从第一个字符开始重新比较,KMP算法的改进在于:当匹配中出现字符不相等时,主串指针不回溯,模式串指针根据部分匹配的结果,尽可能的向右“滑动”一段距离,从而减少匹配次数。
kmp算法可以在O(n+m)的时间数量级上完成串的模式匹配操作。
算法匹配过程如下:

这里可以看到第三次匹配时,模式串没有从头开始,而是直接比较了b,这是KMP算法的难点之一,即当匹配过程中产生失配时,主串中的第i个字符应该与模式中哪个字符比较呢?

这里我们以模式串s="abaab"为例,假设在比较s[3]处失配了,那么这时再比较可以从s[1]处开始,因为我们知道s[0]~s[2]匹配成功,即s[2]对应的主串位置应为’a’,s[0]=s[2]所以s[0]不需要再次匹配直接放到之前s[2]所在的位置即可,不难发现,这里移动的位置应该与模式串的前缀字符串和后缀字符串有关,这就是下面要讲的next数组。

next数组

next[j]=k:表示当模式中的第j个字符与主串中相应字符失配时,在模式串中需重新和主串中该字符进行比较的字符位置。

注:下标从1开始

j 1 2 3 4 5 6 7 8
模式串 a b a a b c a c
next[j] 0 1 1 2 2 3 1 2

KMP代码

int Index_KMP(string S, string T, int pos)
{//利用模式串T的next函数求T在主串S中第pos个字符之后的位置//其中T非空,1<=pos<=S.lengthint i = pos; int j = 1;while (i <= S.length() && j <= T.length()){if (j == 0 || S[i] == T[j])//匹配成功,继续比较后续字符{++i;++j;}elsej = next[j];//模式串右移}if (j > T.length())return i - T.length();//匹配成功elsereturn 0;//匹配失败
}

求解next函数

先放一个b站的视频,使用图解法解释代码,非常形象,建议大家直接看视频就好了
https://www.bilibili.com/video/BV16X4y137qw/

next[j]=k,表明在模式串中
“t[1]t[2]…t[k-1]”=“t[j-k+1]t[j-k+2]…t[j-1]”(假设下标从1开始)
此时求解next[j+1]有以下两种情况
1.t[k]=t[j]
则在模式串中有"t[1]t[2]…t[k-1]t[k]“=“t[j-k+1]t[j-k+2]…t[j-1]t[j]”
此时next[j+1]=next[j]+1
2.t[k]≠t[j]
此时可以把求next函数值的问题看成是一个模式匹配的问题,整个模式串既是主串又是模式串,在之前的匹配过程中已经有"t[1]t[2]…t[k-1]”=“t[j-k+1]t[j-k+2]…t[j-1]”,则当t[k]≠t[j]时应将模式串向右滑动,比较t[next[k]]和t[j],若t[next[k]]与t[j]相等,则next[j+1]=next[k]+1,若不相等,继续滑动比较t[next[next[k]]]与t[j],如不存在任何相等,则next[j+1]=1。
下面举个例子简单的描述一下这个过程(字有点难看)

next数组求解代码

void get_next(string T, int next[])
{int i = 1;next[1] = 0;int j = 0;while (i < T.length()){if (j == 0 || T[i] == T[j]){++i;++j;next[i] = j;}elsej = next[j];}
}

next数组的修正——nextval数组

前面定义的next函数在某些情况下尚有缺陷。例如模式"aaaab"在和主串"aaabaaaab"匹配的过程中,当i=4,j=4时,s[4]≠t[4],根据next数组还需进行j=3,j=2,j=1这三次比较,实际上这三个字符与第四个字符都是相同的,因此不再需要比较,可以直接比较i=5,j=1。也就是说按上述定义得到next[j]=k,而模式中t[j]=t[k],则当主串中s[i]≠t[j]时,不需要再和t[k]比较,直接和t[next[k]]比较。

j 1 2 3 4 5
模式串 a a a a b
next[j] 0 1 2 3 4
nextval[j] 0 0 0 0 4
void get_nextval(string T, int nextval[])
{int i = 1;nextval[1] = 0;int j = 0;while (i < T.length()){if (j == 0 || T[i] == T[j]){i++;j++;if (T[i] != T[j])nextval[i] = j;elsenextval[i] = nextval[j];}elsej = nextval[j];}
}

KMP算法(严蔚敏数据结构第二版)相关推荐

  1. KMP算法-严蔚敏数据结构

    KMP 算法是 D.E.Knuth.J,H,Morris 和 V.R.Pratt 三位神人共同提出的,称之为 Knuth-Morria-Pratt 算法,简称 KMP 算法.该算法相对于 Brute- ...

  2. 严蔚敏数据结构第二版(p85,3)

    #include <iostream> #include <string> #include <vector> #define MAXSIZE 100 /*习题3 ...

  3. 严蔚敏数据结构c++版微盘_数据结构复习知识点总结

    <数据结构>重点在线性表.树.图.查找和排序.参考书目是<数据结构>(C语言版)严蔚敏.吴伟民编著.通过对线性表.队列.栈和数组的了解,进一步理解其含义,熟悉各种例如进栈.出栈 ...

  4. 严蔚敏数据结构c++版微盘_招聘 | 传智 C 位,等你坐镇~

    传智内部招聘 加入传智播客,享受更多员工福利! 五险一金.补充医疗险.意外险.交通补助.餐补.免费体检.员工旅游.生日福利.节日福利.免费体育健身活动.传智父母节福利等等. 有意请将简历发送到邮箱 z ...

  5. 算法设计题3.16-栈和队列-第3章-《数据结构习题集》-严蔚敏吴伟民版

    习题集完整源码部分 第3章  栈和队列                                                                                 ...

  6. 算法设计题3.27-栈和队列-第3章-《数据结构习题集》-严蔚敏吴伟民版

    习题集完整源码部分 第3章  栈和队列                                                                                 ...

  7. c语言采用顺序存储结构存储串,试编写算法实现串的置换操作,串-第4章-《数据结构题集》答案解析-严蔚敏吴伟民版...

    习题集解析部分 第4章 串 --<数据结构题集>-严蔚敏.吴伟民版 源码使用说明  链接☛☛☛<数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明 课本源码合 ...

  8. 10-1-直接插入排序-内部排序-第10章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第10章  内部排序 - 直接插入排序 --<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版>(严蔚敏,吴伟民版)课 ...

  9. 7-5-无向图生成树-图-第7章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第7章  图 - 无向图生成树 --<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+ ...

最新文章

  1. Disucz!高级幻灯片制作
  2. 怎样将两个html页面合并,如何把WORD的两个页面合并在一起?
  3. wcf wpf mfc 区别
  4. 大数据发展历程及技术选型
  5. 电气计算机基础知识,电气基础知识
  6. 实对称矩阵的特征值求法_【8】实(反)对称矩阵的特征值
  7. 软件项目管理第一章作业答案
  8. Wireshark通过TCP协议抓取QQ好友IP以及定位
  9. 服务器pci-e硬盘,来一发干货,PCI-E SSD硬盘使用须知
  10. AutoCAD中禁用shift+鼠标中键组合作为动态观察的功能
  11. 微信群发助手怎么使用?微信群发助手怎么发?
  12. https工作原理及CA证书部署
  13. It has been compressed and nested jar files must be stored without compression
  14. python实现xlsx批量转xls(或者xls批量转xlsx)
  15. window10 1060 caffe 安装
  16. android 蓝牙传输文件,android-通过蓝牙发送文件
  17. 520表白浪漫的句子文案用便签记下来
  18. Java谣言终结者之Arraylist和Linkedlist到底谁快
  19. jQuery树形控件zTree使用小结
  20. 最强大、最古老、最本源的代码:指令INSTRUCTION

热门文章

  1. 超声波换能器的主要参数解读,全!
  2. 100khz 高频率超声波换能器振子设计
  3. 第六章-“那又如何”:情绪低落为何会使人屈服于诱惑
  4. 关于Revit二次开发的些许事
  5. c语言单片机实训心得体会,单片机实训心得体会_单片机实习感悟与收获
  6. RSA算法原理(二)
  7. 现代化的中国教育,缺失的不是钱,是思想(之一)--“授之以鱼不如授之以渔”的局限性
  8. springboot毕设项目低值易消耗品管理系统的设计和实现13usk(java+VUE+Mybatis+Maven+Mysql)
  9. 长春APP开发公司揭秘让百万用户热门下载的APP制作时掌握的技巧
  10. 什么是反射?如何使用反射