模式匹配- KMP算法

Knuth-Morris-PrattKMP)算法-听我的,别总重来。

发表于1977年的KMP算法是一种高效的匹配算法,消除了BF算法中回溯问题,即每次移的距离可以不是1是更大的数也不需要回溯,BF算法的时间度是O(m*n),而KMP算法的时间度是O(m+n)

 

BF算法中,用模式串去和目标串比较时,如果发生不匹配,就要回溯到起始位置,然后后移。KMP算法的思想是,设法利用这个已知信息,跳过前面已经比较过的位置,继续把它向后移,从而提高效率。

这样,KMP算法有以下两个要点:

(1) 计算跳转位置信息的部分匹配表。

(2) 后移到指定位置,重新开始匹配比较。

 

具体的说,每当一趟匹配过程中出现字符比较不等时,不需要回溯目标串TidxSrc指针,而是利用已经得到的“部分匹配”的结果(模式串PidxPtn位置前面的子串P[0... idxPtn-1]的部分匹配表值将模式串P向右滑(idxPtn - k)个字符,继续进行比较

 

有几个概念:

:指除了最后一个字符以外,一个字符串的全部

后缀:指除了第一个字符以外,一个字符串的全部尾部组合。

最大长度:是"前缀""后缀"的最大的共有元素的长度。

最大度表:模式串的每个字符对应的各个前缀后缀的公共元素的最大长度的一览表。

 

基于最大长度表匹配

失配时,模式串向右移动的位数为:已匹配字符数 - 失配字符的上一位字符所对应的最大长度值。

 

为了确定匹配失败时,下次匹配时idxPtn的位置,引入了next[]数组,next[idxPtn]的值表示模式串P[0... idxPtn-1]中最长后缀的长度等于相同字符序列的前缀。这个next 数组叫做部分匹配表。

 

对于next[]数组的定义如下:

KMP算法的关是在匹配失败时,确定下一次匹配的位置,next[idxPtn]=k,表示当模式串P中第idxPtn个字符与目标T字符不匹配,模式串P当由第k个字符与目串中不匹配的字符对齐继续进行比

 

next构造

                    ┌   -1   idxPtn =0;

next[idxPtn]=│max{k| 0<k< idxPtn P[0,1,...,k-1]=P[idxPtn-k,.. idxPtn -1]}

                   └    0    其他情况

 

根据最大长度表求next数组

next 数组相当于最大长度表整体向右移一位,然后最左端用-1补齐。

 

■基于next 匹配

失配,模式串向右移的位数:失配字符所在位置 - 失配字符对应next 值。

 

next 数组的改进

在模式串中,如果相邻字符相同的话,next 值也要相同。

 

OK,上码。

 

Java的简单实现,仅供娱乐。

 


 





郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。