KMP算法

一.简介

KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败字符前面已匹配字符计算跳转表,子串从跳转表获取下一次比较索引。

定义问题:
主串:
s = S[0,1,2,…,n-1] 字符串长度为n

子串:
p = P[0,1,…,m-1], 字符串长度为m且m<=n

字符串 abcdbcd
真前缀:除最后一个字符外含有头部字符的顺序组合
abcdbc,abcdb,abcd,abc,ab,a 都是真前缀

真后缀:除头部字符外含有最后一个字符的顺序组合
bcdbcd,cdbcd,dbcd,bcd,cd,d 都是真后缀

对于长度为k的字符串,其真前缀(真后缀)长度为:[0,k-1]

暴力匹配

1.从主串的首字符开始,与模式串逐一进行匹配

2.匹配失败时主串回溯到开始匹配索引的下一个索引开始,模式串从0继续开始匹配

3.时间复杂度:O(n * m)

推导:
匹配过程中部分匹配时主串回溯匹配做了很多无用比较。有 k 个匹配字符时的主串与子串有如下关系:

1.S[i,i+1,i+2,…,i+k-1] = P[0,1,…,k-1] 且 S[i+k] 不等于 P[k],k <= m;

2.暴力匹配的下一次比较主串 i = i-k+1,模式串 j = 0,如果回溯会有匹配的可能,定有如下关系:
P[0,1,…,j-1,j] = S[i,i+1,i+j-1],即等价于模式串中最开始的一部分和模式串最后一部分有重叠,即 P[0,1,…,k-1] = P[m-k,m-k+1,…,m-1],否则都是无效比较;

3.基于推论2,此时回溯主串索引已经没有意义(重叠部分一定是相等的),主串索引继续在上次不匹配的位置,回溯模式串索引为 k 再比较即可

基于推论3可知如果提前计算模式串在匹配k个字符时的相等最大真前缀、真后缀就能提高匹配效率。

二.实现

package com.vincent;


import java.util.Arrays;

public class Main {
   
    public static void main(String[] args) throws Exception {
   
        String src = "abcdabcabcde";
        String dst = "abcabc";
        System.out.println(bruteSearch(src,dst));

        int[] table = next(dst);
        System.out
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值