Java 数据结构与算法系列精讲之KMP算法

作者:我是小白呀 时间:2023-05-06 14:55:55 

概述

从今天开始, 小白我将带大家开启 Java 数据结构 & 算法的新篇章.

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

Java 数据结构与算法系列精讲之KMP算法

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

来源:https://iamarookie.blog.csdn.net/article/details/122105073

标签:Java,KMP,算法,数据结构
0
投稿

猜你喜欢

  • java初学者必须理解这几个问题

    2023-04-07 14:22:36
  • Android使用RecyclerView仿美团分类界面

    2022-10-03 09:52:23
  • Java运行时数据区概述详解

    2023-10-08 07:00:10
  • Android实现带列表的地图POI周边搜索功能

    2022-09-17 02:48:35
  • Android.bp语法和使用方法讲解

    2022-09-29 19:31:19
  • java String的intern方法

    2021-07-05 03:23:52
  • springboot配置文件绑定实现解析

    2022-06-07 23:32:38
  • Android启动屏实现左右滑动切换查看功能

    2022-11-02 02:18:02
  • map实现按value升序排序

    2022-10-23 23:13:49
  • Java中线程休眠编程实例

    2021-09-06 11:42:55
  • C语言 MD5的源码实例详解

    2022-12-22 05:37:16
  • java swing标准对话框具体实现

    2021-12-30 02:48:50
  • Java集合之Comparable和Comparator接口详解

    2022-10-04 06:03:44
  • Android编程入门之HelloWorld项目目录结构分析

    2022-07-23 23:34:40
  • SpringCloud feign无法注入接口的问题

    2021-09-04 03:26:29
  • 详解Java实践之建造者模式

    2023-01-14 23:03:13
  • SpringBoot @Import与@Conditional注解使用详解

    2023-12-14 16:42:45
  • 自定义一个异常类模板的简单实例

    2022-04-30 02:53:14
  • Android 自定义标题栏 显示网页加载进度的方法实例

    2023-10-11 09:51:22
  • Spring Security自定义登录原理及实现详解

    2022-11-20 21:57:39
  • asp之家 软件编程 m.aspxhome.com