KMP字符串匹配算法


昨天意外的翻开一本搜索引擎的书,看到了KMP算法,很早以前就听过KMP算法,但是没有深究,最近在搞搜索,所以想深入学习一下KMP算法。KMP算法是一种改进的字符串匹配算法。KMP算法的核心是通过匹配表来提高匹配效率,理解了匹配表就基本理解了KMP算法。核心思想是利用已经得到的部分匹配信息来进行后面的匹配过程。我认为优秀算法的根本是减少不必要的重复计算从而提升效率。

介绍两个概念:

前缀:除字符串的最后一个字符外,所有前缀组合

后缀:除了字符串的第一个字符外,所有后缀组合

例如:Google,前缀:G、Go、Goo、Goog、Googl

后缀:o、oo、oog、oogl、oogle

那么匹配表怎么算呢,找到”前缀和后缀集合中最长匹配的字符串的长度“。

例如:abababca

a的前缀后缀都为空 L=0

ab的前缀为a后缀为b L=0

aba的前缀a、ab后缀a、ba,L=1

abab的前缀a、ab、aba后缀b、ab、bab,L=2

ababa的前缀a、ab、aba、abab后缀baba、aba、ba、a,L=3

ababab的前缀a、ab、aba、abab、ababa后缀babab、abab、bab、ab、b,L=4

abababc的前缀a、ab、aba、abab、ababa、ababab后缀bababc、ababc、babc、abc、bc、c,L=0

abababca的前缀a、ab、aba、abab、ababa、ababab、abababc后缀bababca、ababca、babca、abca、bca、ca、a,L=1

生成匹配表如下

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 |

table[partial_match_length - 1]>利用partial_match_length - table[partial_match_length - 1]计算可以跳过的位移。

例如bacbababaabcbab中匹配abababca

b a c b a b a b a a b c b a b
X
a b a b a b c a

没有匹配,下移一位:

b a c b a b a b a a b c b a b
|
a b a b a b c a

table[partial_match_length - 1]= table[0]) =0,1-0=1.下移一位

b a c b a b a b a a b c b a b
X
a b a b a b c a

未匹配,下移一位,一次类推,直到匹配

b a c b a b a b a a b c b a b
| | | | |
a b a b a b c a

匹配了5项,partial_match_length-5,partial_match_length - table[partial_match_length - 1]=5-table[4]=5-3=2

b a c b a b a b a a b c b a b
a b a a b c a

位移两位的实质是:在已匹配的字符串ababa中,前缀为a、ab、aba、abab,后缀为baba、aba、ba、a,其中前缀和后缀集合中相同项为a、aba,aba最长。正如下面的变换所示,partial_match_length -3=5-3=2.需要移动两位。总匹配长度为5,有3个字符串前缀和后缀是匹配的,所有需要用总匹配长度减去前后缀匹配长度,即为位移数。

a b a b a
| | |
a b a
| | |
a b a

参考:The Knuth-Morris-Pratt Algorithm in my own words

优质内容筛选与推荐>>
1、SQL Server 查询表的记录数(3种方法,推荐第一种)--来自别人的博客
2、javascript深入理解js闭包
3、js 定位到指定位置
4、java.lang.OutOfMemoryError: PermGen space及其解决方法
5、JS时间格式化


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号