KMP算法【字符串搜索算法】

KMP算法

1. 算法核心

  1. 利用匹配失败后的信息
  2. 尽量减少模式串(B)与主串(A)的匹配次数
  3. 以达到快速匹配的目的
  4. 通过一个 next 数组,保存模式串(B)中 前后最长公共子序列的长度,每次回溯时,通过 next 数组找到,前面匹配过的位置,省去了大量的计算时间

2. 如何减少匹配次数

2.1. 字符串的前缀和后缀

比如字符串:ababacb

前缀集合 后缀集合
{a,ab,aba,abab,ababa,ababac} {b,cb,acb,bacb,abacb,babacb}

2.2. 构建next数组

注意:当只有一个元素,它没有最长公共前后缀【next[0] = 0】

3. 代码实现

package com.kmp;

public class KMP {
    static List<Integer> list = new ArrayList<>();

    public static void main(String[] args) {
        String s = "BBC ABCDAB ABCDABCDABDEdsafeABCDABD";
        String target = "ABCDABD";

        int[] next = kmpNext(target);
        kmpSearch(s, target, next);
        System.out.println(list);
    }

    public static List<Integer> kmpSearch(String s, String target, int[] next){  //  2个
        int m = str2.length();

        //  遍历
        for (int i = 0, j = 0; i < str1.length(); i++) {
            while (j > 0 && s.charAt(i) != target.charAt(j)){  //  如果不等了,就一直向前推进,找到上一个相等的位置
                j = next[j - 1];
            }

            if (s.charAt(i) == target.charAt(j)){
                j++;
            }

            if (j == m){
                list.add(i - m + 1);
                j = 0;  //  j 重置【匹配上了之后,j 重头开始匹配】
            }
        }
        return list;
    }

    //  获得一个模式串的 next 数组
    public static int[] kmpNext(String target) {  //  单个
        int[] next = new int[target.length()];
        next[0] = 0;
        for (int i = 1, j = 0; i < target.length(); i++) {
            while (j > 0 && target.charAt(i) != target.charAt(j)){
                j = next[j - 1];
            }

            if (target.charAt(i) == target.charAt(j)) {
                next[i] = ++j;
            }
        }
        return next;
    }
}
posted @   爱新觉罗LQ  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示