【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;
        }
    }
}
相关文章
|
7月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
696 0
|
7月前
|
机器学习/深度学习 算法 机器人
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
340 8
|
7月前
|
机器学习/深度学习 算法 自动驾驶
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
390 8
|
7月前
|
机器学习/深度学习 数据采集 负载均衡
结合多种启发式解码方法的混合多目标进化算法,用于解决带工人约束的混合流水车间调度问题(Matlab代码实现)
结合多种启发式解码方法的混合多目标进化算法,用于解决带工人约束的混合流水车间调度问题(Matlab代码实现)
368 0
|
7月前
|
机器学习/深度学习 人工智能 算法
【基于TTNRBO优化DBN回归预测】基于瞬态三角牛顿-拉夫逊优化算法(TTNRBO)优化深度信念网络(DBN)数据回归预测研究(Matlab代码实现)
【基于TTNRBO优化DBN回归预测】基于瞬态三角牛顿-拉夫逊优化算法(TTNRBO)优化深度信念网络(DBN)数据回归预测研究(Matlab代码实现)
313 0
|
7月前
|
数据采集 分布式计算 并行计算
mRMR算法实现特征选择-MATLAB
mRMR算法实现特征选择-MATLAB
431 2
|
8月前
|
存储 编解码 算法
【多光谱滤波器阵列设计的最优球体填充】使用MSFA设计方法进行各种重建算法时,图像质量可以提高至多2 dB,并在光谱相似性方面实现了显著提升(Matlab代码实现)
【多光谱滤波器阵列设计的最优球体填充】使用MSFA设计方法进行各种重建算法时,图像质量可以提高至多2 dB,并在光谱相似性方面实现了显著提升(Matlab代码实现)
252 6
|
8月前
|
传感器 机器学习/深度学习 编解码
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
361 3
|
7月前
|
机器学习/深度学习 算法 数据可视化
基于MVO多元宇宙优化的DBSCAN聚类算法matlab仿真
本程序基于MATLAB实现MVO优化的DBSCAN聚类算法,通过多元宇宙优化自动搜索最优参数Eps与MinPts,提升聚类精度。对比传统DBSCAN,MVO-DBSCAN有效克服参数依赖问题,适应复杂数据分布,增强鲁棒性,适用于非均匀密度数据集的高效聚类分析。
|
8月前
|
机器学习/深度学习 传感器 算法
【高创新】基于优化的自适应差分导纳算法的改进最大功率点跟踪研究(Matlab代码实现)
【高创新】基于优化的自适应差分导纳算法的改进最大功率点跟踪研究(Matlab代码实现)
385 14