KMP算法学习

原创 2016年08月30日 18:56:34

简单模式匹配最坏复杂度在:O(n*m)
KMP可以牛到在O(n+m)的时间数量级上完成串的模式匹配操作。
核心来了:
改进:每当一次匹配过程中出现字符比较不等时,不需要回溯i指针(主字符串),而是利用已经得到的”部分匹配”的结果将模式向右”滑动”尽可能远的一段距离,继续进行比较。

所以核心在于,向右滑动多少距离怎么计算。
终于搞得懂了,记录一下。

设主串是S,模式串是P。
用i指针在S串中游动,j指针在P串中游动。不用考虑i,j是从0开始计数还是从1开始计数。任选一个,这里我选择从1计数。
也即:S1S2S3….Sn
P1P2P3….Pm
上面我们说,核心在于失配时,模式串尽可能向右滑动远的一段距离
这是感性的说法,用可量化的语言描述是:当S[i] != P[j]时,i指针不要回溯,而是想,S[i]和P[k]再比较,这样只需要针对模式串进行研究

以下是数学推导:

失配时,已经部分匹配的是:P1P2…Pj-1 = Si-j+1Si-j+2…Si-1

注意下标。
假设此时应与模式中第k个进行比较,必须要满足的条件是:
模式串中前k-1个字符的字串必须和S[i]前面k-1个字符匹配。
即:

      P1P2...Pk-1 = Si-k+1Si-k+2…Si-1  (1)

此时让S[i]与P[k]比较,所以部分匹配满足:

      Pj-k+1Pj-k+2…Pj-1 = Si-k+1Si-k+2..Si-1  (2)

这里的j仍是当前未回溯的j的值。其实,在失配时:

    P1P2...Pj-1 = Si-j+1...Si-1,上面只是选取一部分与(1)可联立方程。

所以由(1) (2)可以推导出:

      P1P2…Pk-1 = Pj-k+1Pj-k+2…Pj-1(*)

也就得到了在失配时,如何仅仅根据模式串自身就能找到k的公式了。

P[1]=P[jk+1]P[2]=P[jk+2]P[3]=P[jk+3]...P[k1]=P[j1]

左边序号是升序,右边也是升序。因此,寻找的k值是:失配字符之前前缀和后缀相等的最大长度+1

特别注意k的含义是:指向下一个与文本串比较的在模式串中的位置,而前缀和后缀相等是公共部分,长度+1后才是k的位置。

令next[j] = k,我们就得到了常用的函数:

next[j] = 0, 当j = 1时
next[j] = max{k|1 < k < j 且P1P2…Pk-1 = Pj-k+1Pj-k+2…Pj-1,此集合不空}
next[j] = 1,其他情况

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

所以是基于j指针进行k的寻找,j是失配时候的值。

有了next[j]函数,那么匹配过程就可以描述为:

假设以指针i和j分别致使主串和模式中正待比较的字符,令i的初值为1.

若在匹配过程中,Si = Pj,则i++,j++
否则失配,i保持不变,j回退到next[j],即: j = next[j].再比较Si和Pj
若回退到j为0,则表示第一个字符就失配,此时需要主串的下一个位置开始于模式重新开始匹配。

以后再补代码。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

KMP算法学习&amp;总结

  • 2013年10月24日 19:15
  • 156KB
  • 下载

字符串单模板匹配学习笔记(一)kmp算法

【参考资料】 先上链接: 《字符串匹配的KMP算法》-阮一峰 http://kb.cnblogs.com/page/176818/ 《字符串匹配算法总结》 http://blog.csdn....

KMP算法学习三阶段由浅入深

—————————————————————————————————————————————————————————————————————————————       写在前面的话:        ...

KMP算法及字符串匹配学习

KMP算法是一个效率很高的字符串匹配算法。 我们先看一下朴素的字符串匹配算法,将模式串的每一位与原串进行匹配,如果发生失配现象,则要将原串向前挪一位,以此类推,直到匹配成功为止,设模式串的长度为n,原...
  • zjq_01
  • zjq_01
  • 2017年06月09日 19:46
  • 232

KMP算法相关学习资料

KMP算法学习资料和相关文章推荐。

数据结构(C语言描述)(王爱民 李杰)清华大学出版学习课后题第三章(顺序表,链表,串的KMP算法)

顺序表 了解顺序表的前提就是知道什么是线性表,线性表的概念非常的简单,就是除了头和尾元素之外的所有元素都有一个前驱和一个后继,满足这样要求的我们基本上都可以定义为线性表。 那么线性表我们在这里会讲...

KMP算法学习总结

今天看了不少关于KMP算法的东东 读了好几篇别人写的博客 零零碎碎的算是大体明白是个怎么回事儿了  现在好好把别人的东西 整理整理 部分是转载的哦! KMP算法核心: 1、KMP算法借助于一个辅...

吾之简单的KMP算法学习,字符串操作基本功

字符与文字 字符如此普遍,构成我们语言的文字在电脑以看来字符为单位是十分合理的,我们人类的任何语言都对文字赋予了丰富的内涵,处理好每一个字符是一个负责任的一流工程师应该做的。即便是简单到不能再简单的L...
  • Syudf
  • Syudf
  • 2015年12月30日 20:39
  • 299

学习kmp算法

介绍kmp算法,包含kmp算法的完整代码。

学习KMP算法的一点个人体会

这篇文章是对基于阶段性学习动态规划的一个实践性算法体会的记录,KMP算法,也就是大名鼎鼎的字符匹配算法,想必大家对这个字符匹配算法的目的已经很了解了,我最开始学习这个算法的时候其实也是主要是对算法中的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:KMP算法学习
举报原因:
原因补充:

(最多只允许输入30个字)