字符串之KMP

KMP是字符串匹配的常见算法有多种变形,下面仅仅讨论下经典的KMP算法:

a)    kmp算法主要是先计算Pattern串p的特性,利用的是一个nextPos[]数组。

    1)nextPos[0] == -1;

    2)如果nextPos[j] == k,则:'p0 ... pk-1' == 'pj-k+1 ... p j-1'    (1<k<j)。且没有k' > k满足此等式,即k是最大的。

    3)如果nextPos[j]==k,那么假如主串的当前char和pattern的第j个char不匹配,那么Pattern向前移动,使得主串当前char和Pattern的第k个比较,如果成功则继续匹配,如果不成功则Pattern按照nextPos[k]==s继续移动,如此循环。

    4)原因:1. 在2)中等式可以保证串'p0 ... pk-1' 必然匹配。2. 由于k是最大的所以保证了正确性。

    5)问题就集中在如何求nextPos数组。首先其过程也是一个匹配过程和主匹配极其相似。整个Pattern既是主串又是模式串。

    6)nextPos由自“底”向“上”求得。极像动态规划过程:nextPos[i+1] =       nextPos[i] + 1     (pk == pi

                                                                                                            nextPos[m] + 1    (pm != pi

 m动态求得(见程序的注释)。求到的nextPos[n]==k必定是满足2)中等式的最大k(最优子结构!!)。此便是bellman动态规划过程!仔细体会下。

 

 

b)    setPattern函数中有语句   (注释attention)

                if(pattern.charAt(i) != pattern.charAt(j)){
                    nextPos[i] = j;           //如果不等则有机会和主串的当前字符匹配
                }else{
                    nextPos[i] = nextPos[j];     //在相等的情况下,既然charAt(i)不匹配则charAt(j)也不匹配,继续向前找。
                }                                              //由于等价的传播,只要向前一次即可。

                和最基本的KMP算法等价语句比较:

                nextPos[i] = j;

         多加一个if语句判断是一个小技巧,由于nextPos[i]==j,是当主串当前字符和pattern.charAt(i)“失”配的情况下,Pattern要向右移动,直到Pattern的第j个字符和主串当前字符比较,那么如果pattern.charAt(i) == pattern.charAt(j) 则主串当前字符和 pattern.charAt(j)也必然“失”配,所以在这种情况下用最基本的KMP就会进行不必要的比较了。 

 

 

c)     if(j == -1 || mainString.charAt(i) == pattern.charAt(j))里面有bool表达式的短路判断才能使得charAt(j)永远不会等于-1

 

 

 上面是我的考虑,代码下有KMP比较经典的介绍:

-------------------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------------------------------

 

 

http://blog.csdn.net/Oneil_Sally/archive/2008/12/03/3440784.aspx

严蔚敏版数据结构80页

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值