KMP算法及其应用(JAVA)

基本介绍

  1. KMP是一个解决模式串在文本串是否出现过,如果出现过,最早出现的位置的经典算法
  2. KMP算法利用之前判断过信息,通过一个next数组,保存模式串中前后最长公共子序列的长度,每次回溯时,通过next数组找到,前面匹配过的位置,省去大量时间

代码实现

public class KMPAlogrithm {
    public static void main(String[] args) {
        //测试
        String str1="BBC ABCDAB ABCDABCDABDE";
        String str2="ABCDABD";

        int[] next=kmpNext(str2);
        System.out.println("Next"+ Arrays.toString(next));

        int index=kmpAlogrithm(str1,str2,next);
        System.out.println("index="+index);
    }

    //KMP搜索算法

    /**
     *
     * @param str1  字符串
     * @param str2  要寻找匹配的字符串
     * @param next  部分匹配值表
     * @return   匹配到的索引位置,-1则为未匹配到
     */
    public static int kmpAlogrithm(String str1,String str2,int[] next){
        for(int i=0,j=0;i<str1.length();i++){
           //当str1.charAt(i)!=str2.charAt(j),调整j的大小
            //KMP算法的核心点
            while(j>0&&str1.charAt(i)!=str2.charAt(j)){
                j=next[j-1];
            }
            if(str1.charAt(i)==str2.charAt(j)){
                j++;
            }
            if(j==str2.length()){
                //表示已经找到了
                return i-j+1;
            }
        }
        return -1;
    }


    //获取到一个子串的部分匹配值
    public static int[] kmpNext(String str){
        //创建一个数组用于记录部分匹配值
        int[] next=new int[str.length()];
        next[0]=0;  //当长度为1时,部分匹配值为0
        for(int i=1,j=0;i<str.length();i++){
            //当str.charAt(i)!=str.charAt(j)我们需要从next[j-1]获取新的j
            //知道发现有str.charAt(i)==str.charAt(j)成立才退出
            //此为KMP算法的核心点
            while(j>0&&str.charAt(i)!=str.charAt(j)){
                j=next[j-1];
            }
            //当str.charAt(i)==str.charAt(j)满足是,部分匹配值+1
            if(str.charAt(i)==str.charAt(j)) {
                j++;
            }
            next[i]=j;
        }
        return next;
    }

}

关于理解 j=next[j-1]:
[https://www.bilibili.com/video/BV15t41117Qr?from=search&seid=5391930078374506400]
http://www.cnblogs.com/SYCstudio/p/7194315.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值