最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之KMP算法

 更新時間:2022年02月18日 09:15:58   作者:我是小白呀  
在很多地方也都經(jīng)??吹街v解KMP算法的文章,看久了好像也知道是怎么一回事,但總感覺有些地方自己還是沒有完全懂明白。這兩天花了點時間總結(jié)一下,有點小體會,我希望可以通過我自己的語言來把這個算法的一些細(xì)節(jié)梳理清楚,也算是考驗一下自己有真正理解這個算法

概述

從今天開始, 小白我將帶大家開啟 Java 數(shù)據(jù)結(jié)構(gòu) & 算法的新篇章.

KMP 算法

KMP (Knuth-Morris-Pratt), 是一種改進(jìn)的字符串匹配算法. KMP 算法解決了暴力匹配需要高頻回退的問題, KMP 算法在匹配上若干字符后, 字符串位置不需要回退, 從而大大提高效率. 如圖:

舉個例子 (字符串 “abcabcdef” 匹配字符串 “abcdef”):

次數(shù) 暴力匹配 KMP 算法 說明
1 abcabcdef abcdef abcabcdef abcdef a 和 a 匹配
2 abcabcdef abcdef abcabcdef abcdef ab 和 ab 匹配
3 abcabcdef abcdef abcabcdef abcdef abc 和 abc 匹配
4 abcabcdef abcdef abcabcdef abcdef abca 和 abcd 不匹配, 回退. 暴力匹配回退到索引 1, 即 “b”, KMP 算法索引跳置 3, 即 “a”
5 abcabcdef abcdef abcabcdef abcdef 暴力匹配 b 和 a 不匹配, 后移. KMP 算法 a 和 a 匹配
6 abcabcdef abcdef abcabcdef abcdef 暴力匹配 c 和 a 不匹配, 后移. KMP 算法 ab 和 ab 匹配
7 abcabcdef abcdef abcabcdef abcdef 暴力匹配 a 和 a 匹配. KMP 算法 abc 和 abc 匹配
8 abcabcdef abcdef abcabcdef abcdef 暴力匹配 ab 和 ab 匹配. KMP 算法 abcd 和 abcd 匹配
9 abcabcdef abcdef abcabcdef abcdef 暴力匹配 abc 和 abc 匹配. KMP 算法 abcde 和 abcde 匹配
10 abcabcdef abcdef abcabcdef abcdef 暴力匹配 abcd 和 abcd 匹配. KMP 算法 abcdef 和 abcdef 匹配 , 匹配完成
11 abcabcdef abcdef abcabcdef abcdef 暴力匹配 abcde 和 abcde 匹配. KMP 算法匹配完成
12 abcabcdef abcdef abcabcdef abcdef 暴力匹配 abcd 和 abcd 匹配, 匹配完成. KMP 算法匹配完成

部分匹配表

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

舉個例子, 字符串 “ABCDABD” 的前綴與后綴:

字符串 前綴 后綴 共同部分
A NaN NaN NaN 0
AB A B NaN 0
ABC A, AB C, BC NaN 0
ABCD A, AB, ABC D, CD, BCD NaN 0
ABCDA A, AB, ABC, ABCD A, DA, CDA, BCDA A 1
ABCDAB A, AB, ABC, ABCD, ABCDA B, AB, DAB, CDAB, BCDAB AB 2
ABCDAB A, AB, ABC, ABCD, ABCDA, ABCDAB D, BD, ABD, DABD, CDABD, BCDABD NaN 0

KMP 算法實現(xiàn)

重點:

KMP 算法中移動的位數(shù) = 已匹配的字符數(shù) - 對應(yīng)的部分匹配值

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) {

        // 定義數(shù)組
        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);
    }
}

輸出結(jié)果:

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

到此這篇關(guān)于Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之KMP算法的文章就介紹到這了,更多相關(guān)Java KMP 算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

社会| 望江县| 鸡东县| 宣汉县| 通渭县| 丽江市| 乳源| 大关县| 锦州市| 密云县| 壤塘县| 会宁县| 哈巴河县| 故城县| 公安县| 清水河县| 梓潼县| 濉溪县| 甘谷县| 大名县| 灵宝市| 会东县| 岱山县| 永清县| 休宁县| 恩平市| 镇巴县| 晋城| 横峰县| 年辖:市辖区| 长垣县| 甘孜县| 皋兰县| 高雄市| 屏东县| 页游| 家居| 垣曲县| 体育| 和政县| 桑日县|