KMP算法求回溯数组的步骤
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算法求回溯数组的步骤相关推荐
- KMP算法求next数组
1.简介 Knuth-Morris-Pratt 算法,简称 \text{KMP}KMP 算法,由 \text{Donald Knuth}Donald Knuth.\text{James H. Morr ...
- KMP算法求Next数组的个人理解(类同qq炫舞)
最近学了韩顺平老师发布在b站上的数据结构与算法课,发现kmp算法中,求取Next数组的方法有点难理解,下面说一说我自己的感悟. 我感觉求这个数组和玩qq炫舞是一样的,是要达成一种comboo,连续达成 ...
- KMP算法之next数组详解
KMP算法之next数组详解 KMP算法实现原理 KMP算法是一种非常高效的字符串匹配算法,下面我们来讲解一下KMP算如何高效的实现字符串匹配.我们假设如下主串和模式串: int i;//i表示主串的 ...
- KMP算法 → 计算next数组
[KMP算法简介] KMP算法中的next数组仅取决于模式串本身,而与相匹配的主串无关. KMP算法中的next数组,是KMP算法的核心. KMP算法是由克努特(Knuth).莫里斯(Morris)和 ...
- KMP算法 → 计算nextval数组
[算法解析] ● 众所周知,KMP算法中模式串T的next数组,是KMP算法的核心. next数组的核心作用是"当模式串T的第j位与主串S的第pos位失配时(即 T[j]≠S[pos] 时) ...
- KMP算法的next数组通俗解释
我们在一个母字符串中查找一个子字符串有很多方法.KMP是一种最常见的改进算法,它可以在匹配过程中失配的情况下,有效地多往后面跳几个字符,加快匹配速度. 当然我们可以看到这个算法针对的是子串有对称属性, ...
- 数据结构与算法之KMP算法中Next数组代码原理分析
2019独角兽企业重金招聘Python工程师标准>>> 一.KMP算法之Next数组代码原理分析 1.Next数组定义 当模式匹配串T失配的时候,Next数组对应的元素指 ...
- KMP算法及next数组(最大公共前后缀)求解
KMP算法及next数组(最大公共前后缀)求解 2020.12.14理解: 1. KMP算法 网上关于KMP算法讲解较为简单易懂,因此在此只作简述: 在字符串s中匹配字符串t: S: ABE-AB-A ...
- 看了这个你基本就会算kmp算法的next数组了
看了这个你基本就会算kmp算法的next数组了 kmp算法的next数组求解在计算机专业考研中,以及在大学的数据结构考试中等场合可能会遇到,而遇到后,可能很多同学绕绕脑袋,抓抓头发,却发现还是做不来. ...
最新文章
- 7714天,王小川正式卸任搜狗CEO!用一瞬间定格永恒
- 26.C++- 泛型编程之类模板(详解)
- Trees Made to Order ZOJ - 1062
- 2022-02-07
- Python学习总结15:时间模块datetime time calendar (二)
- 机器学习 客户流失_通过机器学习预测流失
- 微软超融合私有云测试11-SCVMM2016部署之添加Hyper-V集群
- 平面直角坐标系中的旋转公式_【数理之路】初中范围推导三角函数倍角正弦公式...
- 全球英文经典演讲100篇_日语演讲100问(1)即兴演讲不即兴!(理论篇)
- UCan下午茶杭州站:突破困惑,为大数据商业化变现探寻出路
- 免费HTML5期末大作业:我的家乡网站设计——可根据百度百科--曹县
- Camera-roll,pitch,heading
- 网络安全专题报告:零信任安全,数字时代的主流安全架构
- HIVE如何进行随机抽样
- NLP实战之textCNN中文文本分类
- 使用wine在mac系统上运行windows程序
- 程序员创业:小程序开发费用报价表,包含项目工期和费用明细
- ASEMI可控硅模块MTC110-16为何能得到大家的青睐
- [javascript] js删除数组中的元素
- 非官方新人参考之quake3入门碎解