温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java怎么实现KMP算法

发布时间:2022-02-18 10:47:13 来源:亿速云 阅读:250 作者:iii 栏目:开发技术

本篇内容主要讲解“Java怎么实现KMP算法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java怎么实现KMP算法”吧!

KMP 算法

KMP (Knuth-Morris-Pratt), 是一种改进的字符串匹配算法. KMP 算法解决了暴力匹配需要高频回退的问题, KMP 算法在匹配上若干字符后, 字符串位置不需要回退, 从而大大提高效率. 如图:

Java怎么实现KMP算法

举个例子 (字符串 “abcabcdef” 匹配字符串 “abcdef”):

次数暴力匹配KMP 算法说明
1abcabcdef abcdefabcabcdef abcdefa 和 a 匹配
2abcabcdef abcdefabcabcdef abcdefab 和 ab 匹配
3abcabcdef abcdefabcabcdef abcdefabc 和 abc 匹配
4abcabcdef abcdefabcabcdef abcdefabca 和 abcd 不匹配, 回退. 暴力匹配回退到索引 1, 即 “b”, KMP 算法索引跳置 3, 即 “a”
5abcabcdef abcdefabcabcdef abcdef暴力匹配 b 和 a 不匹配, 后移. KMP 算法 a 和 a 匹配
6abcabcdef abcdefabcabcdef abcdef暴力匹配 c 和 a 不匹配, 后移. KMP 算法 ab 和 ab 匹配
7abcabcdef abcdefabcabcdef abcdef暴力匹配 a 和 a 匹配. KMP 算法 abc 和 abc 匹配
8abcabcdef abcdefabcabcdef abcdef暴力匹配 ab 和 ab 匹配. KMP 算法 abcd 和 abcd 匹配
9abcabcdef abcdefabcabcdef abcdef暴力匹配 abc 和 abc 匹配. KMP 算法 abcde 和 abcde 匹配
10abcabcdef abcdefabcabcdef abcdef暴力匹配 abcd 和 abcd 匹配. KMP 算法 abcdef 和 abcdef 匹配 , 匹配完成
11abcabcdef abcdefabcabcdef abcdef暴力匹配 abcde 和 abcde 匹配. KMP 算法匹配完成
12abcabcdef abcdefabcabcdef abcdef暴力匹配 abcd 和 abcd 匹配, 匹配完成. KMP 算法匹配完成

部分匹配表

部分匹配表 (Partial Match Table) 指的是 “前缀” 和 “后缀” 的最长共有元素的长度.

举个例子, 字符串 “ABCDABD” 的前缀与后缀:

字符串前缀后缀共同部分
ANaNNaNNaN0
ABABNaN0
ABCA, ABC, BCNaN0
ABCDA, AB, ABCD, CD, BCDNaN0
ABCDAA, AB, ABC, ABCDA, DA, CDA, BCDAA1
ABCDABA, AB, ABC, ABCD, ABCDAB, AB, DAB, CDAB, BCDABAB2
ABCDABA, AB, ABC, ABCD, ABCDA, ABCDABD, BD, ABD, DABD, CDABD, BCDABDNaN0

KMP 算法实现

重点:

KMP 算法中移动的位数 = 已匹配的字符数 - 对应的部分匹配值

import java.util.Arrays;

public class KMPMatch {

    public static int Match(String str1, String str2, int[] next) {

        // 初始化索引
        int i = 0;
        int j = 0;

        for (; i < str1.length(); i++) {

            if (j > 0 && str1.charAt(i) != str2.charAt(j)) {
                // 不匹配, 回退
                i = i - next[j - 1];
                j = 0;
            }

            // 匹配
            if (str1.charAt(i) == str2.charAt(j)) {
                j++;
            }

            // 返回索引
            if (j == str2.length()) {
                return i - j + 1;
            }
        }
        return -1;
    }

    // 部分匹配
    public static int[] getNext(String s) {

        // 定义数组
        int next[] = new int[s.length()];

        // 初始化i, j
        int i = 0;
        int j = -1;
        next[0] = -1;

        // 遍历
        while (i < s.length() - 1) {
            if (j == -1 || s.charAt(i) == s.charAt(j)) {
                // 匹配成功
                next[i] = j + 1;
                i++;
                j++;
            } else {
                //一旦不匹配成功j回退到-1
                j = -1;
            }
        }
        return next;
    }


    public static void main(String[] args) {

        // 字符串1
        String str1 = "BBCABCDAB ABCDABD";

        // 字符串2
        String str2 = "ABCDABD";

        // 匹配表
        int[] next = getNext(str2);
        System.out.println(Arrays.toString(next));


        // KMP算法
        int result = Match(str1, str2, next);
        System.out.println(result);
    }
}

输出结果:

[0, 0, 0, 0, 1, 2, 0]
10

到此,相信大家对“Java怎么实现KMP算法”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI