码迷,mamicode.com
首页 > 编程语言 > 详细

KMP算法

时间:2014-11-26 01:16:49      阅读:250      评论:0      收藏:0      [点我收藏+]

标签:blog   http   os   问题   log   ad   ef   时间   new   

  KMP算法时间复杂度为O(m+n),直观地看,是因为在匹配过程中指针 i 没有回溯。KMP算法的核心思想是利用已经得到的部分匹配信息来进行后面的匹配过程。

  KMP算法思路:从主串s的第pos个字符起和模式的第一个字符比较之,若相等,继续逐个比较后继字符。当一趟匹配过程中出现字符比较不等时,不回溯指针,而是利用已经得到的“部分匹配”的结果将模式串向右“滑动”尽可能远的一段距离后,继续进行比较。

  思考的开始: 假定:主串为 ‘S1S2…Sn’ 模式串为‘ P1P2…Pm’ 无回溯匹配问题变为:当主串中的第i个字符和模式串中的第j个字符出现不匹配(si不等于pj)时,主串中的第i个字符应该和模式串中的哪个字符匹配?

  进一步思考: 将模式串“向右滑动”,让模式串中第k(k<j)个字符和si对齐继续比较。这时有: ‘ P1P2…Pk-1 ‘ = ‘ Si-k+1Si-k+2…Si-1 ‘

  (1) 而根据部分匹配成功的结果可知: ‘P1P2…Pj-1 ‘ = ‘Si-j+1Si-k+2…Si-1 ‘

  (2) 由(2)式 ‘Pj-k+1Pj-k+2…Pj-1 ‘ = ‘Si-k+1Si-k+2…Si-1

‘   (3) 由(1)和(3)有:

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

  由(4)可知,若模式串中的前k-1个字符与模式串中pj字符前面的k-1个字符相等时,则当匹配过程中,主串中第i个字符与模式中第j个字符比较不等时,仅需将模式p“向右滑动”至致使Pk和Si对准,此时,模式中头k-1个字符的子串‘ P1P2…Pk-1 ‘必定与主串中第i个字符之前长度为k-1的子串‘ Si-k+1Si-k+2…Si-1 ‘相等。因此,匹配仅需从模式中第k个字符与主串中第i个字符比较起继续进行。

  关于next函数的解释:

引用出处(以下为引用点击转到原文)

bubuko.com,布布扣

  "部分匹配值"就是"前缀"和"后缀"的最长的共有元素的长度。以"ABCDABD"为例,

  - "A"的前缀和后缀都为空集,共有元素的长度为0;

  - "AB"的前缀为[A],后缀为[B],共有元素的长度为0;

  - "ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;

  - "ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;

  - "ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1;

  - "ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2;

  - "ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。

  16.

bubuko.com,布布扣

  "部分匹配"的实质是,有时候,字符串头部和尾部会有重复。比如,"ABCDAB"之中有两个"AB",那么它的"部分匹配值"就是2("AB"的长度)。搜索词移动的时候,第一个"AB"向后移动4位(字符串长度-部分匹配值),就可以来到第二个"AB"的位置。

KMP算法

标签:blog   http   os   问题   log   ad   ef   时间   new   

原文地址:http://www.cnblogs.com/leetao94/p/4122288.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!