9.KMP算法

2023-05-16

KMP算法

1.KMP算法解决的问题

字符串str1和str2,str1是否包含str2,如果包含返回str2在str1中开始的位置,如果不包含返回-1。如果做到时间复杂度O(N)完成?

测试用例:str1 = “ABC1234de”, str2 = “1234”.返回3。

1.1最大相等前后缀

如一个序列abbabbk,求字符k的最大相等前后缀。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-34XjHgui-1649841326326)(C:\Users\ThinkStation K\AppData\Roaming\Typora\typora-user-images\1649840893670.png)]

因此,序列abbabbk中k的最大相等前后缀长度为3。注意:

  1. 前后缀是k之前的序列的前后缀不包括k。
  2. 最大相等前后缀长度不能是前后缀的整体,这样没有意义。

1.2next数组

对str2的每一个字符都求它位置之前的字符子串的最大相等前后缀长度,形成了一个next数组。

如:str2 = "aabaabs",求str2的next数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NWfMSnQt-1649841326327)(C:\Users\ThinkStation K\AppData\Roaming\Typora\typora-user-images\1649841305073.png)]

  • **下标0位置之前没有子串,**没有前后缀,因此认为规定next[0] = -1。
  • **下标1位置有子串a,**前后缀只有a,但最大相等前后缀长度不包括整个前后缀,因此认为规定next[1] = 0.
  • 下标2位置有子串aa,前后缀有a,因此2位置的最大相等前后缀为1。
  • 以此类推。

1.3KMP匹配过程

如:str1 = “abbstkscabbstks”, str2 = “abbstkscabbstkz”

在这里插入图片描述

尝试str1从0位置,str2从0位置,str1是否能匹配str2,当来到下标14位置时才第一次出现str1[14] != str2[14]。

如果是经典过程(暴力双循环)则会来到str1从下标1位置,str2继续从0位置来判断str1能否匹配str2。而KMP加速过程如下:

str2在下标14位置的最大相等前后缀长度为6,则str2会跳到下标6位置开始与str1的14位置字符继续比较。

在这里插入图片描述

这个匹配过程有两个实质:

  1. 其实就相当于str1来到8的j位置(14 - 6)与str2来到0位置开始比较str1是否能匹配出str2,只不过str2中z的最长相等前后缀长度为6,0~5位置的字符不用比较就能知道相等。

  2. 从i到j中间任何一个位置都不能匹配出str2。证明如下:

    (1)假设i和j任意一个位置k能匹配出整个str2。

    (2)str1(k….14 - 1)可以与str2(0…14 - k - 1)匹配。

    (3)但是str1(k…14 - 1)与str2(k….14 - 1)相同。

    (4)也就是说str2(0…14 - k - 1)与str2(k…14 - 1)相同,也就是说str2的最大相等前后缀长度为k。然而k < j,我们已经求出str2的最大相等前后缀长度为14 - j ,假设这种情况的最大相等前后缀为14 - k > 14 - j,也就是说如果k位置能够匹配出str2,那么str2最大相等前后最长度为14 - k > 14 - j,超出str2本来的最大相等前后缀长度,前后矛盾,因此假设不成立。

在这里插入图片描述

1.4next数组求法

  1. next[0]人为规定为-1,next[1]认为规定为0,next[2]看str2[0]和str2[1]是否相等,相等则next[2] = 1,否则next[2] = 0。
  2. next[3]可以根据next[0]、next[1]、next[2]求出;next[4]可以根据next[0]、next[1]、next[2]、next[3]求出…依次类推
  3. 假设来到i位置,可以知道next[i - 1]的位置k,如果str2[k] == str2[i],则next[i] = next[i - 1] + 1。否则跳到next[k]位置,如果str2[next[k]] == str2[i],则next[i] = next[i] = next[k] + 1。依次类推。有点抽象,看如下跳转的例子。

【例子】str2 = abbstabbecabbstabb?。?为可变字符。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x5Sf47Wx-1649841326327)(C:\Users\ThinkStation K\AppData\Roaming\Typora\typora-user-images\1649839594414.png)]

1.5KMP代码

vector<int> getNext(const string &s) {
	if (s.size() == 1) {
        return {-1}; 
    }	    
    vector<int> next(s.size());
    next[0] = -1;
    next[1] = 0;
    int i = 2;   //next数组位置
    int cn = 0;  //用哪个位置的字符和i - 1位置的字符比,也代表当前使用的最大相等前后缀长度是多少
    while (i < next.size()) {
        if (s[i - 1] == s[cn]) {
            next[i++] = ++cn;
        } else if (cn > 0) { //当前跳到cn位置的字符,和i - 1位置字符配不上
            cn = next[cn];
        } else {
            next[i++] = 0;
        }
    }
    return next;
}

int strStr(string str1, string str2) {
    if (str1.size() < str2.size() || str2.size() == 0) {
        return -1;
    }
    int i1 = 0, i2 = 0;
    //得到str2的next数组
    vector<int> next = getNext(str2);
    while (i1 < str1.size() && i2 < str2.size()) {
        if (str1[i1] == str2[i2]) {
            ++i1;
            ++i2;
        } else if (next[i2] == -1) { //i2 == 0,无法向前跳
            ++i1;
        } else {
            i2 = next[i2];
        }
    }
    //i1越界或者i2越界
    return i2 == str2.size() ? i1 - i2 : -1; 
}	
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

9.KMP算法 的相关文章

  • 串的模式识别和kmp算法

    串的简单模式匹配 与 KMP 获取next数组 参考书籍 王道 数据结构 代码验证软件 xff1a vs2019 include lt iostream gt typedef char SString 暴力比对 S abcabaaabaab
  • JAVA代码实现字符串匹配(一)——BF、KMP

    话不多说 xff0c 直接进入主题 xff1a 题目描述 xff1a 给定两个字符串text和pattern xff0c 请你在text字符串中找出pattern字符串出现的第一个位置 xff08 下标从0开始 xff09 xff0c 如果
  • KMP算法

    一 何谓模式串匹配 模式串匹配 xff0c 就是给定一个需要处理的文本串 xff08 理论上应该很长 xff09 和一个需要在文本串中搜索的模式串 xff08 理论上长度应该远小于文本串 xff09 xff0c 查询在该文本串中 xff0c
  • ZJM 与纸条(KMP算法)

    问题描述 ZJM 的女朋友是一个书法家 xff0c 喜欢写一些好看的英文书法 有一天 ZJM 拿到了她写的纸条 xff0c 纸条上的字暗示了 ZJM 的女朋友 想给 ZJM 送生日礼物 ZJM 想知道自己收到的礼物是不是就是她送的 xff0
  • [week15] C - ZJM与纸条(选做)—— KMP算法

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 ZJM 的女朋友是一个书法家 xff0c 喜欢写一些好看的英文书法 有一天 ZJM 拿到了她写的纸条 xff0c 纸条上的字暗示了 ZJM 的女朋友 想给 ZJM
  • hdu 1358 Period KMP

    题目大意 xff1a 对于一个字符串 xff0c 找由循环字符串组成的位置 xff0c 并输出最多循环了几次 xff0c 比如两个样例 xff0c 第一个是 aaa xff0c 所以在第二个位置由子串a循环两次得到 xff0c 第三个位置由
  • 9.KMP算法

    KMP算法 1 KMP算法解决的问题 字符串str1和str2 xff0c str1是否包含str2 xff0c 如果包含返回str2在str1中开始的位置 xff0c 如果不包含返回 1 如果做到时间复杂度O N 完成 xff1f 测试用
  • Cyclic Nacklace 【HDU - 3746】【KMP补周期】

    KMP算法的讲解 自己的领悟可随时提问 题目链接 题意 有一个字符序列 现在问你 序列后面最少补充几个元素使其恰能成为几个重复循环的序列 题目还是很良心的 让我们求字符串后面放几个字符可以使其变成周期字符串 所以还是可以想到用KMP的nex
  • KMP算法原理详解_论文解读版

    1 KMP算法 KMP算法是一种保证线性时间的字符串查找算法 由Knuth Morris和Pratt三位大神发明 而算法取自这三人名字的首字母 因而得名KMP算法 那发明这样的字符串查找算法又有什么用 在当时计算机本身非常昂贵 计算资源更是
  • Simpsons’ Hidden Talents【KMP模板题】

    Homer Marge I just figured out a way to discover some of the talents we weren t aware we had Marge Yeah what is it Homer
  • 超详细超全超好理解的KMP算法

    定义 KMP算法是一种字符串匹配算法 用于在一个主串中查找一个模式串的出现位置 先看这个视频 再看下边的代码实现 油管阿三哥讲KMP查找算法 中英文字幕 人工翻译 简单易懂 https www bilibili com video BV18
  • 剪花布条 【HDU - 2087】【KMP模板题】

    KMP教学链接 不懂的可以在线问 题意 2个字符串A B 问A中有多少个字符串B Input 输入中含有一些数据 分别是成对出现A B A和B不会超过1000个字符 如果遇见 字符 则表示测试结束 Output 输出B的个数 每个结果之间应
  • KMP算法之基础思想篇

    KMP算法是快速求字符串P 是不是字符串S的子串的一个算法 具体案例呢 可以看力扣的28题 实现 strStr 题意也很简单 就是找出P在S中出现的第一个位置 实际上就是找子串 这种最简单的方法就是暴力 直接两层for循环 O n m 的复
  • 使用共享 MVI 架构实现高效的 Kotlin Multiplatform Mobile (KMM) 开发

    使用共享 MVI 架构实现高效的 Kotlin Multiplatform Mobile KMM 开发 文章中探讨了 Google 提供的应用架构指南在多平台上的实现 通过共享视图模型 View Models 和共享 UI 状态 UI St
  • kmp算法(最简单最直观的理解,看完包会)

    本文将以特殊的方式来让人们更好地理解kmp算法 不包括kmp算法的推导 接下来 我们将从朴素算法出发 在这之前 我们先设主串为S 模式串为T 我们要解决的询问是主串中是否包含模式串 即T是否为S的子串 版权声明 本文为原创文章 转载请标明出
  • 数据结构中Java实现KMP与BF算法对比

    public class KMPANDBF public int indexBfCount SeqString s SeqString t int begin int slen tlen i begin j 0 int count 0 sl
  • LeetCode 1967. 作为子字符串出现在单词中的字符串数目(BM、KMP)

    给你一个字符串数组 patterns 和一个字符串 word 统计 patterns 中有多少个字符串是 word 的子字符串 返回字符串数目 子字符串 是字符串中的一个连续字符序列 示例 1 输入 patterns a abc bc d
  • 【扩展KMP】POJ_3450| HDU_2328 Corporate Identity

    原题直通车 POJ 3450 Corporate Identity HDU 2328 Corporate Identity 题意概述 找出N个串中最长公共子串 分析 一 可以直接枚举其中一个串的所有字串 跟所有串进行匹配找到结果 二 用其中
  • Oulipo

    点击打开链接 Problem Description The French author Georges Perec 1936 1982 once wrote a book La disparition without the letter
  • Count the string【KMP】

    It is well known that AekdyCoin is good at string problems as well as number theory problems When given a string s we ca

随机推荐

  • re.search()用法详解

    re search xff1a 匹配整个字符串 xff0c 并返回第一个成功的匹配 如果匹配失败 xff0c 则返回None pattern 匹配的规则 string 要匹配的内容 flags 标志位 这个是可选的 就是可以不写 可以写 比
  • re.findall()用法详解

    re findall xff1a 函数返回包含所有匹配项的列表 返回string中所有与pattern相匹配的全部字串 xff0c 返回形式为数组 示例代码1 xff1a 打印所有的匹配项 import re s 61 34 Long li
  • Linux系统中创建虚拟环境详解

    1 方法一 1 1 安装虚拟环境的命令 xff1a sudo pip install virtualenv sudo pip install virtualenvwrapper 1 2 安装完虚拟环境后 xff0c 如果提示找不到mkvir
  • 使用python将图片改为灰度图或黑白图

    使用python将图片改为灰度图或黑白图有三种方式 xff0c 分别是是使用cv2库和PIL库来实现 xff0c 详细过程如下所示 1 使用cv2库将图片改为灰度图 在使用cv2进行读取原彩色图片时 xff0c 在里面添加一个参数cv2 I
  • 虚拟机中windows镜像下载与安装

    镜像文件下载 xff1a 链接 xff1a https pan baidu com s 1VKWMHHCGRwWXk2GpxyUp0A 提取码 xff1a shlg 注意 xff1a 虚拟机中的镜像和本地电脑系统安装的镜像是一样的 安装教程
  • mongo数据库中字符串型正负数值比较大小

    数据库中数据展示 xff1a 使用python代码实现 xff1a Requires pymongo 3 6 0 43 from pymongo import MongoClient client 61 MongoClient 34 mon
  • flask项目中内部接口调用其他内部接口操作

    1 requests 在 Flask 框架项目中 xff0c 可以通过使用 requests 模块来进行内部接口调用 requests 模块是 Python 中常用的 HTTP 请求库 xff0c 可以用于发送 HTTP 请求和处理响应 示
  • ElasticSearch删除索引中的数据(delete_by_query)

    1 删除两个月以前的数据 在 Elasticsearch 中 xff0c 要删除两个月以前的数据 xff0c 可以通过以下步骤 xff1a 计算当前时间的两个月前的日期 xff0c 可以使用 Python 的 datetime 模块来实现
  • Qt Creator子图绘制

    Qt中在一个窗体文件内画所有图显然是不好维护的 xff0c 我们可以将主窗体拆分为几个子窗体 xff0c 在子窗体中绘制子图 xff0c 这样便于我们去维护我们的代码 1 在工程文件中右键 gt Add New 2 选择Qt 设计师界面 3
  • MessageFilter [target=odom ]: Dropped 100.00% of messages so far.问题解决

    错误提示 WARN 1580994954 426403779 MessageFilter target 61 odom Dropped 100 00 of messages so far Please turn the ros gmappi
  • 电磁循迹智能车基于stm32cubeMX、HAL库—我的第一辆智能车

    我的第一辆智能车 电磁循迹智能车 提示 本文适用于初学 想完成一个基础四轮车练练手者 大佬还请勿喷 不过欢迎提出意见 有纰漏之处我将及时纠正 注 工程代码链接已贴在文末 前言 所用到的硬件平台 stm32f103c8t6 舵机 电机 L29
  • 2022年国赛建模B题思路与程序

    B题 无人机遂行编队飞行中的纯方位无源定位 关键词搜索 xff1a 无人机 xff0c 无源定位 其实这个工作特别多 xff0c 知网一堆 xff0c 如果选这个题一定要想好做的出彩 xff0c 另外网上的场景和本题不是很一样 xff0c
  • 2017全国大学生电子设计竞赛:室内可见光定位装置

  • 基于FreeRTOS下多任务的同时操作

    FreeRTOS移植及多任务的实现 前言 xff1a 一 FreeRTOS移植 xff08 1 xff09 移植准备工作 xff08 2 xff09 FreeRTOS移植到stm32中 xff08 3 xff09 例程验证 二 多任务实现
  • undefined symbol 问题解决记录

    历经一个月 xff0c 昨日完成打印机network部分的编写 c语言 xff0c 编写makefile构建动态库 构建完成后遂进行调用测试 xff0c 出现 xff1a network symbol lookup error usr li
  • 2.O(NlogN)的排序算法

    认识O NlogN 的排序算法 1 剖析递归行为及其时间复杂度的估算 递归过程 xff1a 递归过程是一个多叉树 xff0c 计算所有树的结点的过程就是利用栈进行后序遍历 xff0c 每个结点通过自己的所有子结点给自己汇总信息之后才能继续向
  • 4.二叉树的遍历(C++版)

    二叉树的递归 1 二叉树递归遍历 二叉树的递归序 递归序过程 xff1a 两个注释1之间的代码代表第一次来到一个节点的时候 xff0c 会判断一下这个节点是否为空 xff1b 来到这个节点的左树去遍历 遍历完第二次回到本函数 xff0c 进
  • 6.暴力递归转动态规划

    动态规划 1 什么是动态规划 xff1f 动态规划就是暴力递归 xff08 回溯 xff09 的过程中有重复调用的过程 xff0c 动态规划在算过每次调用后把答案记下来 xff0c 下次再遇到重复过程直接调用这个行为就叫动态规划 动态规划就
  • 8.岛问题

    岛问题 题目 一个矩阵中只有0和1两种值 xff0c 每个位置都可以和自己的上 下 左 右四个位置相连 xff0c 如果有一片1连在一起 xff0c 这个部分叫做一个岛 xff0c 求一个矩阵中有多少个岛 xff1f 例子 0 0 1 0
  • 9.KMP算法

    KMP算法 1 KMP算法解决的问题 字符串str1和str2 xff0c str1是否包含str2 xff0c 如果包含返回str2在str1中开始的位置 xff0c 如果不包含返回 1 如果做到时间复杂度O N 完成 xff1f 测试用