首页 > 编程语言 >KMP算法

KMP算法

时间:2023-03-20 15:56:07浏览次数:56  
标签:... int needle next 算法 str KMP 字符串

KMP算法

简介

一种由Knuth(D.E.Knuth)、Morris(J.H.Morris)和Pratt(V.R.Pratt)三人设计的线性时间字符串匹配算法。该算法主要解决的就是字符串匹配的问题。
本文参考前缀函数与KMP算法-oi.wiki

例题

LeetCode 28:找出字符串种第一个匹配项的下标
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。
如果 needle 不是 haystack 的一部分,则返回  -1 。

1 <= haystack.length, needle.length <= 104

haystack 和 needle 仅由小写英文字符组成

输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。

前置知识

  • 字符串前缀
    假设有一个字符串 s[0...i] (下标为0 - i)
    它的前缀就定义为 s[0...j] (j <= i),当 j < i 时,就定义为该字符串的真前缀
  • 字符串后缀
    同理
    后缀定义为 s[j...i] (j >= 0), 当 j > 0 时,就定义为该字符串的真后缀

前缀函数 next[] 数组

next数组是KMP的核心

定义

给定一个长度为 n 的字符串 s,其 前缀函数 被定义为一个长度为 n 的数组 next。 其中 next[i] 的定义是:
如果子串 s[0...i] 有一对相等的真前缀与真后缀:s[ 0...k-1 ] 和 s[ i-(k-1)...i ] ( k-1 < i-(k-1) ),那么 next[i] 的值就是这个字符串最长的真前后缀(因为相等的真前后缀可能不止一对,所以需要的是最长的真前后缀)的长度,也就是 next[i] = k;
next[i] = max(k,max) //条件:([0...k-1] == s[i-(k-1)...i])
初始化 next[0] = 0

举例

对于字符串: a b a b a b a c
next 数组:[ 0,0,1,2,1,2,3,0 ] => "","","a","ab","a","ab","aba",""

暴力求解 next 数组

给定字符串 s
暴力求解:
双指针遍历 s,设双指针 i 为当前 s[0...i] 的前缀和的下标(截至下标),j 为遍历 0 - i 的下标(遍历匹配 s[j] 和 s[i-j])
假设字符串 s[0...i] => j 遍历 比较 s[0] == s[i] ... s[1] == s[i-1] ... s[j] == s[i-j] (需要满足要求 j < i-j )
代码如下(Java):

public static int[] prefixFunction(String str){
    int[] next = new int[str.length()];
    // next[0] = 0; // 可以省略,默认为 0
    for(int i = 1; i < str.length(); i++){
        for(int j = 0; j < i; j++){
            // 截取 str[0...j] 和 str[i-j...i] 比较 
            if(i-j > j && str.substring(0,j+1).equals(str.substring(i-j,i+1))){
                next[i] = j+1;
            }
        }
    }
    return next;
}
时间复杂度 O(n^3) 不推荐使用
优化思想
  • 优化 1
    对于 next[i] ,当 s[i] == s[next[i-1]] 时 可以有 next[i] = next[i-1] + 1: (为什么呢

    标签:...,int,needle,next,算法,str,KMP,字符串
    From: https://www.cnblogs.com/pupilxiao/p/17236341.html

相关文章

  • [算法竞赛进阶指南]货舱选址
    来源:《算法竞赛进阶指南》,模板题算法标签排序,贪心题目描述在一条数轴上有N家商店,它们的坐标分别为A1~AN。现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都......
  • 数据结构与算法:二叉树专题
    数据结构与算法:二叉树专题​​前言​​​​前提条件​​​​基础知识​​​​二叉树链式存储结构​​​​二叉树中序遍历​​​​二叉树层序遍历​​​​常见编程题​​​​......
  • DJBX33A哈希(Hash)算法
    1DJBX33A算法原理2DJBX33A算法典型实现2.1PHP(zend_string.h)2.2Apache(apr_hash.c)2.3BerkeleyDB(src\hash\hash_func.c)2.4Python(pyhash.c)3DJBX33A......
  • python实现一个遗传算法
    ###################  importrandom#染色体长度CHROMO_LENGTH=20#种群大小POP_SIZE=50#交叉概率CROSS_RATE=0.8#变异概率MUTATE_RATE=0.01#......
  • 基于matlab的CHPSO异质粒子群优化算法仿真
    1.算法描述粒子群优化算法(ParticleSwarmOptimization,PSO)最初由Kenndy和Eberhart博士于1995年提出,是一种有效的随机全局优化技术,具有原理简单、参数少、收敛速度较快......
  • 【通信】基于Matlab模拟自适应SCMA资源调度算法设计
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 双指针算法
    一、常见类型(1)对于一个序列,用两个指针维护一段区间(如:快排) (2)对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作(如:归并排序) 二、模板1for(i......
  • 算法思维:思考问题的一种方式
    方法论:万物皆朴素的第一性原理几乎任何领域的任何问题的解决方案,都可以看作是“某个结构上的朴素方法的优化“。计算机只能处理规模有限的问题,在给定规模且不考虑效率的......
  • 数学知识模板之欧几里得算法
    欧几里得算法求最大公约数intgcd(inta,intb){ returnb?gcd(b,a%b):a;}扩展欧几里得算法//x,y是使x*a+y*b=d的一组解intexgcd(inta,intb,int......
  • 时间复杂度--大O记算法
       EG:  ......