KMP算法

简化:

​ 第一步简化,找寻主串S中和模式串P第一个字母相同的字母,这个需要遍历主串,无法优化,在比较的时候寻找就行。

​ 第二部优化,保持主串位置不动,优化模式串移动的位置,朴素匹配法移动一个位置。但在前一轮的比较中,我们已经知道了P的前(j-1)位与S中间对应的(i-1)个元素已经匹配成功了。这就意味着,在一轮的尝试匹配中,我们get到了主串的部分内容,我们能否利用这些内容,让P多移几位(MP算法优化点),减少遍历的趟数呢?答案是肯定的。

​ 分析可知(具体可参考文章底部博文链接),每次失配,S串的索引i不动,P串的索引j定位到某个数。时间效率明显提高。而这“定位到某个数”,这个数就是接下来引入的next值。

难点在求next()值这。

next():

公式如下

image.png

推理:

有公式可知,next值的重点就是求p1...pk--1=pj-k+1...pj-1时k的最大值,即模式串首(p1...pk--1)尾(pj-k+1...pj-1)重合部分的最大值。

有定义可知

j=1

​ next[1] = 0;

没有任何匹配的情况下

​ next[j] = 1;

首尾重合的时候:

当j+1时,它的最大首尾重合部分有可能为

当p1...pj--1=p2...pj => next[j] = j

当p1...pj--2=p3...pj-1 => next[j] = j-1

当p1...pj--3=p4...pj-1 => next[j] = j-2

。。。

当p1pj2=pj-1...pj => next[j] = 3

当p1=pj-1=> next[j] = 2

当p1!=pj-1=> next[j] = 1

如果我们已经知道 next[j] = k,即 p1...pk-1 = pj-k+1...pj-1 时,此时 next[j+1]是多少呢?有两种情况:

当pk=pj,即:p1...pk = pj-k+1...pj,(1<k<j)且不存在大于k的数字,使p1...pk-=pj-k+1...pj成立。此时为next[j+1] = k+1。(代码第四行)。

这里加一句话:读到这里时我有个疑问,当pk=pj,如果主串的Si!=pj,那么Si!=pk,那么此时next[j+1] = k+1就不成立了,后来一想,如果Si!=pj,那也就不会去比较Si+1!=pj+1,也就和next[j+1]没什么关系了。

当pk!=pj,即:p1...pk != pj-k+1...pj,我们需要在pj-k+1...pj中找寻一个子串,假设长度为k',使p1...pk‘ = pj-k’+1...pj成立,也就是在p1...pk中存在一个子串,使p1...pk‘ = pk-k’+1...pk,这个等式换个角度一看,把k’当k,k当j,你会发现,这个其实就是求j = k的next值,因为k<j,所以在前面我们已经求过,直接拿过来用就可。(代码第五行)

又上述过程得出传说中的5行代码:

void getNext(char[] chars,int len,int[] next){
    next[1] = 0; int i=1,j=0;
    while(i<len){
        if(j == 0 || chars[i] == chars[j]) next[++i] = ++j;
        else j = next[j];
    }
}

参考博文:

https://blog.csdn.net/qq_37969433/article/details/82947411

《数据结构(c语言版)》,严蔚敏老师版。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容

  • 字符串匹配KMP算法详解 1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有...
    张晨辉Allen阅读 2,380评论 0 3
  • 姓名:赵应鹏 学号19011210552 【嵌牛导读】:在给定一个文本字符串和一个模式字符串的时候,在文本字符串中...
    小白110阅读 940评论 0 0
  • 文章大纲:1.KMP算法概念2.KMP算法中最核心的next[] 数组是如何生成的3.使用KMP算法 匹配字符串 ...
    柠檬乌冬面阅读 804评论 0 3
  • 前言 在上一篇文章字符串匹配算法(一)——BF算法提到过,字符串匹配的思路是固定的: 将模式串和主串进行比较从前往...
    懒成铁阅读 348评论 0 0
  • 在介绍kmp算法之前,我想先简单介绍一下Brute-Force算法,这是一个回溯的字符串模式匹配算法,是一个简单暴...
    topCoder阅读 1,428评论 0 1