【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;
        }
    }
}
相关文章
|
22天前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
38 3
|
1天前
|
算法 容器
令牌桶算法原理及实现,图文详解
本文介绍令牌桶算法,一种常用的限流策略,通过恒定速率放入令牌,控制高并发场景下的流量,确保系统稳定运行。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
令牌桶算法原理及实现,图文详解
|
10天前
|
负载均衡 算法 应用服务中间件
5大负载均衡算法及原理,图解易懂!
本文详细介绍负载均衡的5大核心算法:轮询、加权轮询、随机、最少连接和源地址散列,帮助你深入理解分布式架构中的关键技术。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
5大负载均衡算法及原理,图解易懂!
|
11天前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
15 3
|
10天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
16天前
|
算法 数据库 索引
HyperLogLog算法的原理是什么
【10月更文挑战第19天】HyperLogLog算法的原理是什么
24 1
|
23天前
|
机器学习/深度学习 人工智能 算法
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
58 0
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
|
16天前
|
缓存 分布式计算 监控
优化算法和代码需要注意什么
【10月更文挑战第20天】优化算法和代码需要注意什么
15 0
|
21天前
|
算法
PID算法原理分析
【10月更文挑战第12天】PID控制方法从提出至今已有百余年历史,其由于结构简单、易于实现、鲁棒性好、可靠性高等特点,在机电、冶金、机械、化工等行业中应用广泛。
|
23天前
|
机器学习/深度学习 算法 数据建模
计算机前沿技术-人工智能算法-生成对抗网络-算法原理及应用实践
计算机前沿技术-人工智能算法-生成对抗网络-算法原理及应用实践
23 0
下一篇
无影云桌面