KMP字符串匹配算法

字符串匹配算法

KMP算法

KMP算法是Knuth,Morris和Pratt三人设计的线性时间字符串匹配算法。不管是网上还是书上介绍的这个算法都很复杂,让人看了头都麻了,但是它的算法思路是很简单的,就是尽可能地利用已知的信息,从而减少尝试匹配的次数。
什么叫尽可能地利用已知的信息呢?
假设我们有字符串T,要在T中匹配出字符串P。
假如匹配进行到如下图的过程,从T的第5个字符a开始的后五个字符都与P的前五个字符匹配上了,但是此时第六个字符匹配失败。
如果采用一般的思路,就将T的匹配位置往后移一位,从第6个字符开始重新匹配,很明显匹配不上,然后在后移一位,依此类推。这样虽然简单,但时间复杂度也高。
其实KMP算法就是尽可能地减少匹配的次数。已经匹配过的字符串就尽量不要再进行重新匹配了。如图,我们在p的第六个字符匹配失败了,所以需要将从头开始匹配,但是是否可以不从头开始呢?
当然可以啦,仔细观察会发现p字符串中c前面的三个字符与p字符串开头的三个字符是完全一致的!而c前面的这三个字符与T字符串匹配上了呀。所以也就是说,p不用从头开始匹配了,从第四个字符开始匹配即可。

在这里插入图片描述

在这里插入图片描述

上面的思路是什么意思呢?
T说:p啊,你来匹配我,看看我们能不能匹配上
P说:好啊
然后p就拿着自己的字符一个一个地跟T去匹配,一直都匹配得挺顺利的,直到第q个字符
T说:不行,这个字符不对。从我的下一个位置重新来!
P很委屈地说:啊!我都匹配了q个字符了,匹配上这么多了,我真的不想从头再一个一个地来啊…
T想了想就说:不重新开始也行,你找找看自己最前面有没有字符跟我后面的这几个字符一样的啊?
P很高兴地说:有啊!有三个,就跟你后面的这三个一毛一样的!
T就说:行吧,你最开始的那三个就不用重新跟我匹配了,从第四个开始和我匹配吧

在这个算法中,最重要的就是P记录每一个字符的一个前缀。
那这个前缀怎么计算呢,我们以上面的P为例,进行计算,-1表示没有符合的前缀

  • 第一个字符没有前缀,第二个字符b也没有,所以前两个都是-1
  • 下标为2的字符a,下标为0的字符为它的前缀
  • 下标为3的字符b可以拿开始的两个字符作为它的前缀
  • 下标为4的字符a可以拿前三个字符作为它的前缀
  • 以此类推…

这里所谓的前缀指的是从起始字符开始,到t[i]的字符串,与当前字符的前t[i]个字符完全一致的字符串

在这里插入图片描述

那么,代码怎么实现呢?
上代码

public int[] prefix(String p){
   
        int n = p.length();
        int[] pre = new int[n];
        pre[
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值