Java实现KMP算法

比较sub是否是str的子字符串

/**
 * @auther lql
 * @create 2022-09-23 14:13
 **/
public class KMP {
    public static void main(String[] args) {
        // 比较sub是否是str的子字符串
        System.out.println(kmp("ababcaababcaabc","ababcaabc" ));
    }
    private static boolean kmp(String str,String sub){
        int[] next=kmpNext(sub);
        int i=0,j=0;
        while (i<str.length()){
            if(str.charAt(i)==sub.charAt(j)){ // 当前字节匹配,则对比下一个字节
                j++;
                i++;
            }else if(j!=next[j]){ // 当前字节不匹配,sub 右移至已匹配字符串前缀和后缀最长相同字符串后一位
                j=next[j-1];
            }else{ // sub 右移0位,[已匹配字符串前缀和后缀没有相同字符串]
                i++;
            }
            if (j>=sub.length()) // sub匹配到最后一位提前结束循环
                return true;
        }
        return false;

    }

    /**
     * 计算部分匹配表["前缀"和"后缀"最长的共有元素的长度]
     * @param substring
     * @return
     */
    private static int[] kmpNext(String substring){
        int left=0,right=1;
        int[] next=new int[substring.length()];
        int count=0;
        while (right<substring.length()){
            if(substring.charAt(left)==substring.charAt(right)){
                count++;
                next[right]=count;
                left++;
            }else{ // 不匹配重头对比,重新开始累计
                count=0;
                if(left!=0){
                    left=0;
                    continue;
                }
            }
            right++;
        }
        return next;
    }
}

计算部分匹配表

"前缀"和"后缀"最长的共有元素的长度
"前缀"指除了最后一个字符以外,一个字符串的全部头部组合
"后缀"指除了第一个字符以外,一个字符串的全部尾部组合

"ababcaabc"为例

字符串前缀后缀匹配值
a[][]0
ab[a][b]0
aba[a, ab][ba, a]1
abab[a, ab, aba][bab, ab, b]2
ababc[a, ab, aba, abab][babc, abc, bc, c]0
ababca[a, ab, aba, abab, ababc][babca, abca, bca, ca, a]1
ababcaa[a, ab, aba, abab, ababc, ababca][babcaa, abcaa, bcaa, caa, aa, a]1
ababcaab[a, ab, aba, abab, ababc, ababca, ababcaa][babcaab, abcaab, bcaab, caab, aab, ab, b]2
ababcaabc[a, ab, aba, abab, ababc, ababca, ababcaa, ababcaab][babcaabc, abcaabc, bcaabc, caabc, aabc, abc, bc, c]0

KMP算法与暴力匹配算法的区别

KMP算法:16次对比+11次部分匹配表生成对比
在这里插入图片描述
kmp算法

暴力匹配算法:25次对比
暴力匹配算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值