数据结构—KMP 算法:

算法思想:

KMP算法实现寻找主串中子串的位置时,主串指针地址不回退,在比对过程中串仅仅遍历一次,子串的回退可以是与当前主串可重新最多匹配的地址位置。

BF与KMP算法比对:

KMP

BF

主串不用回退

主串回退,回退到此次开始比较的下一位置

子串的回退可以是与当前主串可重新最多匹配的地址位置

子串回退到开始位置

思路展示:

1、首先遍历主串中与子串一致的字符,直至出现无法匹配:

如图:主串与子串的粉色阶段相同,而后面的无法匹配

2、当我们发现,在主串与子串相同的部分内,主串后一部分与子串前一部分相同

如图:主串与子串紫色部分相同

可以设想一下,子串是否可以从紫色结尾的地方重新和主串的当前位置再次做匹配

3、由步骤一则知道,主串与子串粉色部分相同,步骤二引入紫色部分相同,则可以推导出:

推导出:子串的前一部分与子串的后一部分相等

4、由思路推出表达式:

  • 子串此次匹配的结束地址下标位置为 j;
  • 开始下标:0;
  • 紫色结束下标:k-1;
  • 由紫色部分长度、字符都相等,所以长度: k-1-0=j-1-紫色开始下标;
  • 所以紫色开始下标:j-k;

结论:

匹配成功的子串片段中,寻找两个最长且相等的真子串,真子串长度决定子串返回的地址下标

真子串特点:

  1. 一真子串以子串的开头为开头
  2. 另一真子串以子串匹配片段的结尾为结尾
  3. K为子串的长度,也是子串在匹配失败时需要返回的位置

next数组及其练习(重点)

我们由上一个结论所得的K 值,保存得到的数组(next数组)

固定值:

        next[0]=-1;    next[1]=0;

易错:

        1、子串的截断字符不包含在此次子串片段范围内,当前的截断字符的next数组值,由截断前的所有字符作为判断决定

请判断:

        红色为标准错误,绿色为正确答案

        2、子串的真子串比对容易漏掉最长真子串

        红色为标准错误,绿色为正确答案

练习例子:

1:"abacdabcabaae"

      -1001001201231

2:"abacdabcabcde"

      -1001001201200

寻找next[]的固定规律:

  • 当我们已知下标为i 的next数组的值时:next[i]=k;
  • 需要判断子串str[]:str[k] 与 str[i] 是否相等?
  1. 相等: next[++i]=++k;
  2. 不相等:

        此时问题则迭代成为在当前已经遍历的字符串中寻找最长的相等真子串

                ->求当前 str[i+1] 对应的 next数组值

                ->即为 next[k]对应的next数组值

                -> next[++i]=next[k]

KMP算法的实现:

#include <iostream>
#include <string>
#include<assert.h>
using namespace std; //KMP 算法,i 不回退
//思路:
//下标: j-k ...j-1 = 0...k 
//找子串的两个最长真子串!首位两个真子串
//真子串长度为k;(next 数组)
//!注意,当前位置为截断不等位置,此位置的前一个位置为尾int BF(const char* str1, const char* str2, int pos)
{assert(str1 != NULL && str2 != NULL);int len1 = strlen(str1);int  len2 = strlen(str2);int* next = (int*)malloc(sizeof(int) * len1);next[0] = -1;next[1] = 0;int i = 1;int k = 0;while (i+1 < len1){if ((k == -1) || str1[i] == str1[k])next[++i]= ++k;elsek=next[k];}if (pos < 0||pos>=strlen(str1)||str1==NULL||str2==NULL)return -1;int j = 0;i = pos;while(i<len1&&j<len2){if ((j==-1)||(str1[i] == str2[j])){i++;j++;}else{//KMP 算法:i保留在当前位置,与j 再次比较j = next[j];/*BF 算法:j = 0;  i = i - j + 1;*/}}if (j == len2)return i - j;return -1;
}int main()
{const char *str1 = "ababcabcdabcdeabcdabcdd";//const char* str1 = "abcd";const char* str2 = "abcd";int i = 0;int j =0;j = BF(str1, str2, j);while(j!=-1){j = BF(str1, str2, j);printf("返回类比pos位置:%d\n", j);if (j == -1)break;j += strlen(str2);}return 0;
}

时间复杂度:

  1. KMP:O(m+n);主串只遍历一次
  2. BF: O(m*n)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/518663.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OracleXE112、plsqldev1207的安装和基本配置

OracleXE112、plsqldev1207的安装和基本配置 OracleXE112、plsqldev1207的安装和基本配置Oracle安装oracle是什么Oracle两个版本下载安装包 安装OracleXE112_Win64注意&#xff1a;安装到空目录下&#xff1b;输入口令&#xff08;记住啊&#xff01;&#xff09;安装成功&…

线性表试题(二)——顺序表应用

二、综合应用题 01&#xff0e;从顺序表中删除具有最小值的元素&#xff08;假设唯一&#xff09;并由函数返回被删元素的值。空出的位置由最后一个元素填补&#xff0c;若顺序表为空&#xff0c;则显示出错信息并退出运行。 02&#xff0e;设计一个高效算法&#xff0c;将顺序…

Leetcoder Day39| 动态规划part06 完全背包问题

完全背包理论 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 示例&#xff1a; 背包最大…

第 5 章 ROS常用组件动态坐标变换(自学二刷笔记)

5.1.3 动态坐标变换 所谓动态坐标变换&#xff0c;是指两个坐标系之间的相对位置是变化的。 需求描述: 启动 turtlesim_node&#xff0c;该节点中窗体有一个世界坐标系(左下角为坐标系原点)&#xff0c;乌龟是另一个坐标系&#xff0c;键盘控制乌龟运动&#xff0c;将两个坐…

书籍强烈推荐:“计算机界三大神书”之一 ——SICP

文章目录 1. 书籍推荐2. 粉丝福利3. 自主购买 1. 书籍推荐 《计算机程序的构造和解释》&#xff08;Structure and Interpretation of Computer Programs&#xff0c;简记为 SICP&#xff09;是MIT的基础课教材&#xff0c;出版后引起计算机教育界的广泛关注&#xff0c;对推动…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Checkbox)

提供多选框组件&#xff0c;通常用于某选项的打开或关闭。 说明&#xff1a; API version 11开始&#xff0c;Checkbox默认样式由圆角方形变为圆形。 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口…

Android视角看鸿蒙第一课(工程目录)

Android视角看鸿蒙第一课&#xff08;工程目录&#xff09; 导读 鸿蒙马上就来了&#xff0c;这个工作很有可能落到Android开发的头上&#xff0c;既是机遇也是挑战&#xff0c;希望能跟上时代的浪潮&#xff0c;迫不得已开始学习鸿蒙开发&#xff0c;顺带分享记录下 我的学…

数据结构界的终极幻神----树

目录 一.数的概念和分类 种类 二.重点概念 哈希树: 二叉树的线索化 什么是线索化 为什么要线索化 特殊的查找树 完全二叉树 三.手撕完全二叉树(堆) 重点讲解 向上搜索算法 向下搜索算法 一.数的概念和分类 树&#xff08;tree&#xff09;是包含 n(n≥0) [2] 个节…

影响APP广告变现收益的4个关键因素

APP的广告收入&#xff08;IAA&#xff09;展示 * eCPM/1000 IAA收入其实是由广告总展示量和每次展示的平均收入共同决定的。所以&#xff0c;提高IAA收入&#xff0c;我们需要双管齐下&#xff1a;同时提高广告总展示量和平均每次展示的收入。 app广告变现对接点击⬇️链接&…

全志D1s开发板裸机开发之坏境搭建

环境搭建 开发板介绍 张天飞老师编写的《RISC-V体系结构编程与实践》&#xff0c;里面的源码是基于 QEMU 模拟器的&#xff0c;可以认为它是一款虚拟的开发板。如果需要在真实开发板上学习&#xff0c;可以使用百问网的 DongshanPI-D1S 开发板。 DongshanPI-D1S 是百问网推出…

Sora:AI视频生成的新机遇与挑战

随着科技的飞速进步&#xff0c;人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;技术已经深入渗透到社会的各个领域。其中&#xff0c;Sora这类基于AI的视频生成工具因其高度逼真的生成能力而备受瞩目。然而&#xff0c;正如一枚硬币有两面&#xff0…

算法刷题Day2 | 977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II

目录 0 引言1 有序数组列表1.1 我的题解&#xff08;双指针&#xff09;1.2 根据官方解题修改后 2 长度最小的子数组2.1 我的题解2.2 官方滑动窗口&#xff08;双指针&#xff09;题解 3 螺旋矩阵3.1 我的题解 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&…