【kmp算法】原理以及代码实现

简介: 【kmp算法】原理以及代码实现


KMP介绍

KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。
KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。

具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)

文字来源:百度百科

具体实现

x指针:用来做主串索引,y指针:用来做模式串索引。

重点:x不回溯,只通过移动y来匹配。

原理

  1. 开始时x,y都指向各自的第0个位置,当两索引处字符相等,x,y向后移动。
  2. 当不相等时,y移动到next[y]元素对应的位置,x不变
  3. 若y移动到-1处,x,y都向后移动
  4. 当x遍历完成后,若匹配成功,x-y的值即为主串对应模式串开始的第一个字符的索引,若匹配失败,返回-1

next数组

匹配过模式串前缀的“最长可匹配前缀子串”和“最长可匹配后缀子串”的最长共有元素的长度。

  • 例如:ABABC 的 next[y]=2
  • next数组的第一个元素为-1

前缀和前缀组合、后缀和后缀组合

  1. 前缀:去掉字符串最后一个元素后剩下的字符串
  2. 后缀:去掉字符串第一个元素后剩下的字符串

例如:ABABD 前缀就是 ABAB 后缀就是 BABD

  1. 前缀组合:前缀中,带有第一个元素的连续字符串组合
  2. 后缀组合:后缀中,带有最后一个元素的连续字符串组合

例如:ABABD 前缀组合有’A’,‘AB’,‘ABA’,‘ABAB’;后缀组合有:‘D’,‘BD’,‘ABD’,BABD’;

Java代码

import java.util.Arrays;
/**
 * ClassName: KmpTest
 * Description:
 * date: 2021/2/19 10:15
 *
 * @author ZhuQiPeng
 * @since JDK 1.8
 */
public class KmpTest {
    public static void main(String[] args) {
        String desStr = "BABABACABABCABAABD";
        String subStr = "ABABCABAAB";
        int[] next = getNext(subStr);
        System.out.println(Arrays.toString(next));
        int index = kmp(desStr,subStr);
        System.out.println(index);
    }
    public static int[] getNext(String subStr){
        int[] next = new int[subStr.length()];
        next[0] = -1;
        int len = -1, y = 0;
        while (y < subStr.length() - 1){
            if(len == -1 || subStr.charAt(len) == subStr.charAt(y)) {
                y++;
                len++;
                next[y] = len;
            }else{
                len = next[len];
            }
        }
        return next;
    }
    public static int kmp(String desStr, String subStr){
        int x = 0,y = 0;
        int[] next = getNext(subStr);
        while (x < desStr.length() && y < subStr.length()){
            if(y == -1 || subStr.charAt(y) == desStr.charAt(x)){
                x++;
                y++;
            }else{
                y = next[y];
            }
        }
        if (y == subStr.length()){
            return x-y;
        }else{
            return -1;
        }
    }
}
相关文章
|
1天前
|
算法 关系型数据库 C语言
卡尔曼滤波简介+ 算法实现代码(转)
卡尔曼滤波简介+ 算法实现代码(转)
12 4
|
2天前
|
运维 算法
基于改进遗传算法的配电网故障定位(matlab代码)
基于改进遗传算法的配电网故障定位(matlab代码)
|
2天前
|
算法 调度
基于多目标粒子群算法冷热电联供综合能源系统运行优化(matlab代码)
基于多目标粒子群算法冷热电联供综合能源系统运行优化(matlab代码)
|
2天前
|
算法
【免费】基于ADMM算法的多微网电能交互分布式运行策略(matlab代码)
【免费】基于ADMM算法的多微网电能交互分布式运行策略(matlab代码)
|
2天前
|
算法
基于蜣螂优化算法DBO的VMD-KELM光伏发电功率预测(matlab代码+可提供讲解)
基于蜣螂优化算法DBO的VMD-KELM光伏发电功率预测(matlab代码+可提供讲解)
|
2天前
|
算法
基于白鲸优化算法BWO的VMD-KELM光伏发电功率预测(matlab代码+可提供讲解)
基于白鲸优化算法BWO的VMD-KELM光伏发电功率预测(matlab代码+可提供讲解)
|
2天前
|
算法 调度 决策智能
基于元模型优化算法的主从博弈多虚拟电厂动态定价和能量管理(matlab代码)
基于元模型优化算法的主从博弈多虚拟电厂动态定价和能量管理(matlab代码)
|
3天前
|
算法
基于改进粒子群算法的混合储能系统容量优化matlab
基于改进粒子群算法的混合储能系统容量优化matlab
|
1天前
|
存储 算法 数据可视化
基于harris角点和RANSAC算法的图像拼接matlab仿真
本文介绍了使用MATLAB2022a进行图像拼接的流程,涉及Harris角点检测和RANSAC算法。Harris角点检测寻找图像中局部曲率变化显著的点,RANSAC则用于排除噪声和异常点,找到最佳匹配。核心程序包括自定义的Harris角点计算函数,RANSAC参数设置,以及匹配点的可视化和仿射变换矩阵计算,最终生成全景图像。
|
1天前
|
算法 Serverless
m基于遗传优化的LDPC码NMS译码算法最优归一化参数计算和误码率matlab仿真
MATLAB 2022a仿真实现了遗传优化的归一化最小和(NMS)译码算法,应用于低密度奇偶校验(LDPC)码。结果显示了遗传优化的迭代过程和误码率对比。遗传算法通过选择、交叉和变异操作寻找最佳归一化因子,以提升NMS译码性能。核心程序包括迭代优化、目标函数计算及性能绘图。最终,展示了SNR与误码率的关系,并保存了关键数据。
11 1