如果你看不懂KMP算法,那就看一看这篇文章(绝对原创,绝对通俗易懂)

KMP算法,俗称“看毛片”算法,是字符串匹配中的很强大的一个算法,不过,对于初学者来说,要弄懂它确实不易。整个寒假,因为家里没有网,为了理解这个算法,那可是花了九牛二虎之力!不过,现在我基本上对这个算法理解算是比较透彻了!特写此文与大家分享分享!

我个人总结了,KMP算法之所以难懂,很大一部分原因是很多实现的方法在一些细节的差异。怎么说呢,举我寒假学习的例子吧,我是看了一种方法后,似懂非懂,然后去看另外的方法,就全都乱了!体现在几个方面:next数组,有的叫做“失配函数”,其实是一个东西;next数组中,有的是以下标为0开始的,有的是以1开始的;KMP主算法中,当发生失配时,取的next数组的值也不一样!就这样,各说各的,乱的很!

所以,在阐述我的理解之前,我有必要说明一下,我是用next数组的,next数组是以下标0开始的!还有,我不会在一些基础的概念上浪费太多,所以你在看这篇文章时必须要懂得一些基本的概念,例如“朴素字符串匹配”“前缀”,“后缀”等!还有就是,这篇文章的每一个字都是我辛辛苦苦码出来的,图也是我自己画的!如果要转载,请注明出处!好了,开始吧!

假设在我们的匹配过程中出现了这一种情况:

根据KMP算法,在该失配位会调用该位的next数组的值!在这里有必要来说一下next数组的作用!说的太繁琐怕你听不懂,让我用一句话来说明:

返回失配位之前的最长公共前后缀!

好,不管你懂不懂这句话,我下面的文字和图应该会让你懂这句话的意思以及作用的!

首先,我们取之前已经匹配的部分(即蓝色的那部分!)

我们在上面说到next数组的作用时,说到“最长公共前后缀”,体现到图中就是这个样子!

接下来,就是最重要的了!

没错,这个就是next数组的作用了:

返回当前的最长公共前后缀长度,假设为len。因为数组是由0开始的,所以next数组让第len位与主串匹配就是拿最长前缀之后的第1位与失配位重新匹配,避免匹配串从头开始!如下图所示!

(重新匹配刚才的失配位!)

如果都说成这样你都不明白,那么你真的得重新理解什么是KMP算法了!

接下来最重要的,也是KMP算法的核心所在,就是next数组的求解!不过,在这里我找到了一个全新的理解方法!如果你懂的上面我写的的,那么下面的内容你只需稍微思考一下就行了!

跟刚才一样,我用一句话来阐述一下next数组的求解方法,其实也就是两个字:

继承

a、当前面字符的前一个字符的对称程度为0的时候,只要将当前字符与子串第一个字符进行比较。这个很好理解啊,前面都是0,说明都不对称了,如果多加了一个字符,要对称的话最多是当前的和第一个对称。比如agcta这个里面t的是0,那么后面的a的对称程度只需要看它是不是等于第一个字符a了。

b、按照这个推理,我们就可以总结一个规律,不仅前面是0呀,如果前面一个字符的next值是1,那么我们就把当前字符与子串第二个字符进行比较,因为前面的是1,说明前面的字符已经和第一个相等了,如果这个又与第二个相等了,说明对称程度就是2了。有两个字符对称了。比如上面agctag,倒数第二个a的next是1,说明它和第一个a对称了,接着我们就把最后一个g与第二个g比较,又相等,自然对称成都就累加了,就是2了。 

c、按照上面的推理,如果一直相等,就一直累加,可以一直推啊,推到这里应该一点难度都没有吧,如果你觉得有难度说明我写的太失败了。

当然不可能会那么顺利让我们一直对称下去,如果遇到下一个不相等了,那么说明不能继承前面的对称性了,这种情况只能说明没有那么多对称了,但是不能说明一点对称性都没有,所以遇到这种情况就要重新来考虑,这个也是难点所在。

如果蓝色的部分相同,则当前next数组的值为上一个next的值加一,如果不相同,就是我们下面要说的!

如果不相同,用一句话来说,就是:

从前面来找子前后缀

1、如果要存在对称性,那么对称程度肯定比前面这个的对称程度小,所以要找个更小的对称,这个不用解释了吧,如果大那么就继承前面的对称性了。

2、要找更小的对称,必然在对称内部还存在子对称,而且这个必须紧接着在子对称之后。

如果看不懂,那么看一下图吧!

好了,我已经把该说的尽可能以最浅显的话和最直接的图展示出来了,如果还是不懂,那我真的没有办法了!

说了这么多,下面是代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 100void cal_next( char * str, int * next, int len )
{int i, j;next[0] = -1;for( i = 1; i < len; i++ ){j = next[ i - 1 ];while( str[ j + 1 ] != str[ i ] && ( j >= 0 ) ){j = next[ j ];}if( str[ i ] == str[ j + 1 ] ){next[ i ] = j + 1;}else{next[ i ] = -1;}}
}int KMP( char * str, int slen, char * ptr, int plen, int * next )
{int s_i = 0, p_i = 0;while( s_i < slen && p_i < plen ){if( str[ s_i ] == ptr[ p_i ] ){s_i++;p_i++;}else{if( p_i == 0 ){s_i++;}else{p_i = next[ p_i - 1 ] + 1;}}}return ( p_i == plen ) ? ( s_i - plen ) : -1;
}int main()
{char str[ N ] = {0};char ptr[ N ] = {0};int slen, plen;int next[ N ];while( scanf( "%s%s", str, ptr ) ){slen = strlen( str );plen = strlen( ptr );cal_next( ptr, next, plen );printf( "%d\n", KMP( str, slen, ptr, plen, next ) );}return 0;
}

如果有什么问题,欢迎评论指正!还是大一新手,很需要进步!

如果你看不懂KMP算法,那就看一看这篇文章( 绝对原创,绝对通俗易懂)相关推荐

  1. 如果你看不懂KMP算法,一定要看看这个视频!!!!!!!!!!!虽然讲的慢,但是很详细!!!!

    如果你看不懂KMP算法,一定要看看这个视频!!!!!!!!!!!虽然讲的慢,但是很详细!!!! 上:http://v.youku.com/v_show/id_XODYxNjExODQ=.html    ...

  2. 如果 你连 “不要迷恋哥” 都看不懂,这些话 你也就不用看了

    301. 名花虽有主,我来松松土! 302. 强烈抗议广告时间插播电视剧! 303. 对不起!我已经死了!不过谢谢你来看我!今天晚上12点我也去看你! 304. 我喝酒是想把痛苦溺死,但这该死的痛苦却 ...

  3. 标题隐藏_头条官方课程没看就想起好标题?请收藏好这篇文章,不要再犯错了...

    一个会学习的人,在任何领域都会强大无比. 最近看到有很多刚步入自媒体的小白都气馁了,其实大家的处境都差不多,要么就是内容推荐量特别低,要么就是内容很少有人看,有好多人甚至怀疑自己能否再坚持下去. 为了 ...

  4. 文本比较算法Ⅴ——回顾贴,对前面几篇文章的回顾与质疑

    文本比较算法Ⅰ--LD算法 文本比较算法Ⅱ--Needleman/Wunsch算法 文本比较算法Ⅲ--计算文本的相似度 文本比较算法Ⅳ--Nakatsu算法 在写了本系列的前面几篇文章之后.有些网友质 ...

  5. python看不懂怎么办_Python是个什么鬼,看美剧的人不懂也太尴尬了...

    原标题:Python是个什么鬼,看美剧的人不懂也太尴尬了... 看到口碑逆天的影视片上映时,你是不是会这样: 两样放光,急不可待,恨不能先睹为快,巴不得熬夜追完全集?! 今天就安利一个新工具,让你看电 ...

  6. 建筑电气工程设计常用图形和文字符号_建筑水电图纸看不懂?10年老师傅教你看图技巧,分分钟安排...

    1.建筑给排水工程包括: 给水.排水.热水.消火栓.自动喷淋等常用系统,其管道当中流动的是水.(其管道输送介质为水) 2.给排水系统的主要功能: (1)建筑给水系统的任务,就是经济合理地将水由室外给水 ...

  7. 【C语言】看了这篇文章,如果你还不会文件操作的话,我把这篇文章给吃了(doge)

  8. HTML+CSS+JavaScript程序员自制导航搜索页面,炫酷黑客帝国特效源代码,如果你觉得你的搜索页面太乱可以看看这篇文章

    现在的搜索页面广告太多,内容少,不够全面 你可以在我的代码的基础上进行拓展 下面是源代码同时:这是下载地址: https://download.csdn.net/download/qq_4475703 ...

  9. 459. 重复的子字符串-KMP算法

    459. 重复的子字符串 给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成. 示例 1: 输入: s = "abab" 输出: true 解释: 可由子串 & ...

最新文章

  1. ESC/P打印:程序控制打印机自动进退纸
  2. Visual Studio 2008 + Visual Assist X的CUDA2.3编译环境设置[转]
  3. sqlserver 时间格式函数详细
  4. 进入工程制图闪退_安阳职业技术学院机电工程系新能源汽车专业项目答辩
  5. [LeetCode] 3. Longest Substring Without Repeating Characters 题解
  6. jQuery: 仿select下拉框效果,点击空白关闭弹出层,判断是否被mouseover
  7. 500位全球算法开发者零奖金参加阿里云天池大赛 AI预测台风助力防灾减灾
  8. yml文件tab 空格_YAML 文件介绍
  9. 【已解决】wordpress文章页面如何去掉特色图像
  10. @Controller @ResponseBody @RestController的基本含义与使用方法
  11. 计算机公益活动策划书,社会公益爱心活动策划方案模板
  12. rlocfind matlab,绘制根轨迹的MATLAB函数介绍
  13. Android MTK flash兼容
  14. Rigify:关于Rigify生成最终绑定时失败的原因及解决办法
  15. Linux 基本命令入门
  16. 【opencv4.3.0教程】04之基础结构及其常用功能介绍1
  17. JupyterLab教程:程序员的笔记本神器v2.0
  18. 结构数组使用(bushi)
  19. php转换时间戳的一些方法
  20. 手机电脑如何使用OTG连接U盘教程及OTG功能常见问题解答

热门文章

  1. 华为与Qualcomm率先完成TDD制式LTE Cat.1 MDM对接测试
  2. ⑱霍兰德ER*如何选专业?高考志愿填报选专业
  3. 易基因:2023年植物表观转录组研究的最新进展(m6A+m5C)|深度综述
  4. STM32 SWD烧录一次后J-LINK设备消失的问题
  5. 天龙八部游戏服务器防护DDos有哪些方法?
  6. CODING 敏捷实战系列课第五讲:敏捷中国史
  7. 来自Window Presentation Foundation Program Design的读书笔记 (第四篇 下)
  8. 给研华, 控创, 西门子, 凌华, 研祥, 艾迅, 盛博, 诺达佳, 阿普奇 ,桦汉工控机外扩一路,二路CAN,四路等CAN通讯
  9. H3C MAGIC R300千兆双频无线路由拆机
  10. [2022_CVPR_LAV]论文阅读learning from all vehicles