【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;
        }
    }
}
相关文章
|
15天前
|
存储 算法 程序员
C 语言递归算法:以简洁代码驾驭复杂逻辑
C语言递归算法简介:通过简洁的代码实现复杂的逻辑处理,递归函数自我调用解决分层问题,高效而优雅。适用于树形结构遍历、数学计算等领域。
|
12天前
|
存储 人工智能 缓存
【AI系统】布局转换原理与算法
数据布局转换技术通过优化内存中数据的排布,提升程序执行效率,特别是对于缓存性能的影响显著。本文介绍了数据在内存中的排布方式,包括内存对齐、大小端存储等概念,并详细探讨了张量数据在内存中的排布,如行优先与列优先排布,以及在深度学习中常见的NCHW与NHWC两种数据布局方式。这些布局方式的选择直接影响到程序的性能,尤其是在GPU和CPU上的表现。此外,还讨论了连续与非连续张量的概念及其对性能的影响。
33 3
|
16天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
42 1
|
25天前
|
缓存 算法 网络协议
OSPF的路由计算算法:原理与应用
OSPF的路由计算算法:原理与应用
36 4
|
24天前
|
存储 缓存 算法
通过优化算法和代码结构来提升易语言程序的执行效率
通过优化算法和代码结构来提升易语言程序的执行效率
|
25天前
|
存储 算法 网络协议
OSPF的SPF算法介绍:原理、实现与应用
OSPF的SPF算法介绍:原理、实现与应用
60 3
|
1月前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
17天前
|
机器学习/深度学习 人工智能 算法
探索人工智能中的强化学习:原理、算法及应用
探索人工智能中的强化学习:原理、算法及应用
|
17天前
|
机器学习/深度学习 人工智能 算法
探索人工智能中的强化学习:原理、算法与应用
探索人工智能中的强化学习:原理、算法与应用
|
11天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。