KMP算法到底是什么原理就不说了,各种资料上讲的明明白白,下面我就如何用代码来实现做一下说明和记录.

KMP的核心思想就是,主串不回溯,只模式串回溯。而模式串匹配到第几位时失配,要回溯多少,由模式串本身来决定。

而求回溯数组主要思想是:

>模式串同时看做新的主串与模式串,自己匹配自己。

>每次匹配都能产生一个数组值,而这个数组值,就是模式串当前偏移量。

>如果模式串失配位置不是首位,那么,还要确定主串失配位置和模式串的首位是否匹配,因为上次匹配的时候,该位置的数组值已经赋了。

所以这次匹配不需要修改数组值。

>如果模式串失配位置是首位,那么,不需上述判断,直接主串后移一位。

代码流程如下:

1. 把模式串p分别作为主串pm和模式串pp进行匹配。

2. index[0] = 0;

3. 主串从pm[1] -> pm[strlen(p) - 1]循环,每次循环确定一个index[i]。

4. 一个内循环,用模式串(从pp[0]开始)的每一位去匹配主串(主串不回溯,所以它的位置由上次循环来决定)的每一位。

5. index[i] = 当前模式串的下标。

6. 每次循环中,如果匹配,内循环继续比较pm和pp的下一位;如果不匹配(失配),则分2种情况。

7. 情况1,失配时模式串pp的下标不为0,但是我们不确定失配时主串pm失配位置所在的字符是否与匹配串pp的首字符相同,所以,下次匹配要从失配位置开始。

但是,注意,因为在第5步我们在失配位置的index[i]已经赋值了,所以,有可能重复赋值。这一点可以做一些必要判断(如:index[i]是否首次赋值;本次循环是否是

为上次失配而进行的收尾工作)。

8. 情况2,失配时模式串pp的下标为0,所以我们不必担心7中的问题,主串下标直接移到下一位置即可。

由此,整个步骤就完成了。

代码如下:

static int *kmp(int *index, int length, char *pm){for(int i = 0; i < length; i++){index[i] = -200;}//1. pm是主串,pp是模式串char *pp = pm;//2. index[0] = 0index[0] = 0;//3. 因为index[0]已确定,因此主串pm从pm + 1处开始循环。pm += 1;while(*pm != '\0'){int i = -1;//4. 内循环,模式串pp从0开始按位匹配pm的每一位。for(i = 0; i < length; i++){//5. index[pm - pp + i] = iif(index[pm - pp + i] == -200)//index[i]只允许赋值一次。为了防止第7步中【注意】中所说的情况index[pm - pp + i] = i;//6. 如果匹配,则继续循环,否则就是失配,分2种情况。if(pm[i] != pp[i]){//7.失配时模式串位置不为0,这时候pm移动至当前失配的位置。if(i != 0){pm += i;}//8. 失配时模式串位置为0,这时候pm移动到下一位置。else pm++;break;}}}return index;
}

由此,回溯数组确定了。那么kmp要如何使用这个数组呢?

>匹配主串与模式串,如果失配,主串和匹配串都要改变位置,分2种情况

>如果模式串失配位置是0,主串移动到失配的下一位置。如果失配位置不是0,则主串移动到失配位置。

>模式串移动到回溯数组中的指定位置。

代码如下:

int find(char *s, char *p){char *src = s;//主串char *psrc = p;//模式串int pm_len = strlen(pm);int *index = new int[pm_len];kmp(index, pm_len, p);//回溯数组 while(*s != 0){ bool suc = true; int i = -1; for(i = 0; i < strlen(p); i++){if(p[i] != s[i]){//失配, i表示模式串失配位置 //如果失配位置不为0,则移动主串到失配位置。 if(i != 0) s += i;//如果失配位置为0,则移动主串到失配位置的下一位。 else s++; //只要失配,模式串都移动到回溯数组中的指定位置。 p = psrc + index[i]; suc = false; break; } }}//每次模式串匹配完之后,判断是否成功了。 if(suc){delete []index;return s - src; } }delete []index;return -1;}

KMP算法求回溯数组的步骤相关推荐

  1. KMP算法求next数组

    1.简介 Knuth-Morris-Pratt 算法,简称 \text{KMP}KMP 算法,由 \text{Donald Knuth}Donald Knuth.\text{James H. Morr ...

  2. KMP算法求Next数组的个人理解(类同qq炫舞)

    最近学了韩顺平老师发布在b站上的数据结构与算法课,发现kmp算法中,求取Next数组的方法有点难理解,下面说一说我自己的感悟. 我感觉求这个数组和玩qq炫舞是一样的,是要达成一种comboo,连续达成 ...

  3. KMP算法之next数组详解

    KMP算法之next数组详解 KMP算法实现原理 KMP算法是一种非常高效的字符串匹配算法,下面我们来讲解一下KMP算如何高效的实现字符串匹配.我们假设如下主串和模式串: int i;//i表示主串的 ...

  4. KMP算法 → 计算next数组

    [KMP算法简介] KMP算法中的next数组仅取决于模式串本身,而与相匹配的主串无关. KMP算法中的next数组,是KMP算法的核心. KMP算法是由克努特(Knuth).莫里斯(Morris)和 ...

  5. KMP算法 → 计算nextval数组

    [算法解析] ● 众所周知,KMP算法中模式串T的next数组,是KMP算法的核心. next数组的核心作用是"当模式串T的第j位与主串S的第pos位失配时(即 T[j]≠S[pos] 时) ...

  6. KMP算法的next数组通俗解释

    我们在一个母字符串中查找一个子字符串有很多方法.KMP是一种最常见的改进算法,它可以在匹配过程中失配的情况下,有效地多往后面跳几个字符,加快匹配速度. 当然我们可以看到这个算法针对的是子串有对称属性, ...

  7. 数据结构与算法之KMP算法中Next数组代码原理分析

    2019独角兽企业重金招聘Python工程师标准>>> 一.KMP算法之Next数组代码原理分析       1.Next数组定义 当模式匹配串T失配的时候,Next数组对应的元素指 ...

  8. KMP算法及next数组(最大公共前后缀)求解

    KMP算法及next数组(最大公共前后缀)求解 2020.12.14理解: 1. KMP算法 网上关于KMP算法讲解较为简单易懂,因此在此只作简述: 在字符串s中匹配字符串t: S: ABE-AB-A ...

  9. 看了这个你基本就会算kmp算法的next数组了

    看了这个你基本就会算kmp算法的next数组了 kmp算法的next数组求解在计算机专业考研中,以及在大学的数据结构考试中等场合可能会遇到,而遇到后,可能很多同学绕绕脑袋,抓抓头发,却发现还是做不来. ...

最新文章

  1. 7714天,王小川正式卸任搜狗CEO!用一瞬间定格永恒
  2. 26.C++- 泛型编程之类模板(详解)
  3. Trees Made to Order ZOJ - 1062
  4. 2022-02-07
  5. Python学习总结15:时间模块datetime time calendar (二)
  6. 机器学习 客户流失_通过机器学习预测流失
  7. 微软超融合私有云测试11-SCVMM2016部署之添加Hyper-V集群
  8. 平面直角坐标系中的旋转公式_【数理之路】初中范围推导三角函数倍角正弦公式...
  9. 全球英文经典演讲100篇_日语演讲100问(1)即兴演讲不即兴!(理论篇)
  10. UCan下午茶杭州站:突破困惑,为大数据商业化变现探寻出路
  11. 免费HTML5期末大作业:我的家乡网站设计——可根据百度百科--曹县
  12. Camera-roll,pitch,heading
  13. 网络安全专题报告:零信任安全,数字时代的主流安全架构
  14. HIVE如何进行随机抽样
  15. NLP实战之textCNN中文文本分类
  16. 使用wine在mac系统上运行windows程序
  17. 程序员创业:小程序开发费用报价表,包含项目工期和费用明细
  18. ASEMI可控硅模块MTC110-16为何能得到大家的青睐
  19. [javascript] js删除数组中的元素
  20. 非官方新人参考之quake3入门碎解

热门文章

  1. .net 去除特殊字符
  2. 路由和交换机工作原理
  3. Python入门(一)数据类型、循环语句
  4. [Linux] 010 权限管理命令 chmod
  5. ruby gems列表
  6. 顺序表应用6:有序顺序表查询
  7. 【OpenCV】图像代数运算:平均值去噪,减去背景
  8. 如何在Terminal命令行模式下运行Objective-C
  9. 安装ATi显卡驱动后增加的鼠标右键菜单的清理
  10. Eigen/Matlab 使用小结