KMP算法理解

举报
黄大猩 发表于 2020/11/11 21:29:33 2020/11/11
【摘要】 KMP算法理解KMP算法主要用于字符串匹配。本文主要是针对http://jakeboxer.com/blog/2009/12/13/the-knuth-morris-pratt-algorithm-in-my-own-words/的翻译和自己的理解,并没有额外的理论理解。匹配表匹配表这个翻译不算准确,原文为 The Partial Match Table即部分匹配表。这个表也是整个算法的核心...

KMP算法理解

KMP算法主要用于字符串匹配。

本文主要是针对http://jakeboxer.com/blog/2009/12/13/the-knuth-morris-pratt-algorithm-in-my-own-words/的翻译和自己的理解,并没有额外的理论理解。

匹配表

匹配表这个翻译不算准确,原文为 The Partial Match Table即部分匹配表。这个表也是整个算法的核心。

下面以一个例子来具体讲解一下这个表,

这里我们有一个字符串“abababca"

char:  | a | b | a | b | a | b | c | a |
index: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
value: | 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 |

我们得到上面的匹配表,

首先表分为3行,分别为char,index,value。每个字符为一列,本例共8列。

第一第二行很好理解,就是每个字符以及它在字符串中对应的位置(从0开始)


在开始讲解value行,需要先拓展2个概念,即合理前缀(proper prefixes)和合理后缀(proper suffixes)。

合理前缀:即尾部切去部分字符的剩余,例如 “S”, “Sn”, “Sna”, 以及“Snap” 都是”Snape“的合理前缀。

合理后缀:与前缀概念相反,即首部切去部分的剩余,  “agrid”, “grid”, “rid”, “id”, and “d” 是“Hagrid”的合理后缀。


下面引出一句比较绕口的定义:

“pattern中合理前缀与合理后缀相同的集合中,最长的前缀(后缀)的长度”

The length of the longest proper prefix in the (sub)pattern that matches a proper suffix in the same (sub)pattern.


比如我们看第三列,我们截取aba,aba有2个合理前缀即a和ab,2个合理后缀a和ba,他们的交集为a,那么最长的匹配为1,因此value行的第三列的值为1。

第4列截取,abab,合理前缀为a,ab,aba, 合理后缀为b,ab,bab, 交集为{a, ab},最长为2,因此第四列为2.

依次类推我们可以得出全部的匹配表

使用匹配表

使用匹配表可以帮助在字符串匹配过程跳过一些反复匹配的过程,提高匹配效率。

公式是这样的:

如果部分匹配的长度不为0(partial_match_length->pmt),且匹配表中对应的该匹配长度的值大于1(table[partial_match_length]>1 ->t[pmt-1]),我们可以向前跳过partial_match_length-table[partial_match_length-1] ( pmt-t[pmt-1])个字符。

举例来说,我们需要在“bacbababaabcbab”,寻找”abababca"

首先是我们的匹配表,

char:  | a | b | a | b | a | b | c | a |
index: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
value: | 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 |

第一次匹配到

bacbababaabcbab
|
abababca

这里匹配到的长度为1,

pmt=1,  t[pmt-1] = t[1-1] = t[0] = 0, 我们不能跳过任何字符

接着匹配到

bacbababaabcbab
   |||||
   abababca

pmt = 5, t[pmt-1] = t[5-1]=t[4] = 3

pmt-t[pmt-1] = 5-3= 2

可以跳过2个字符,

// x denotes a skip

bacbababaabcbab
   xx|||
     abababca

接着匹配到长度为3的字符串aba

pmt=3

t[pmt-1]=1

可跳过3-1=2个字符串

// x denotes a skip

bacbababaabcbab
     xx|
       abababca

现在匹配字符长度超过了剩下的字符,可以总结目标字符串中不包含我们的pattern。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。