代码随想录笔记|C++数据结构与算法学习笔记-字符串(二)|28. 实现 strStr()、459.重复的子字符串、KMP算法
文章目录
- 卡码网.右旋字符串
- 28. 实现 strStr()
- KMP算法(理论)
- KMP算法(代码)
- C++代码
- 459.重复的子字符串
- 暴力解法
- 移动匹配
- KMP解法
卡码网.右旋字符串
卡码网题目链接
略
28. 实现 strStr()
力扣题目链接
文字链接:28. 实现 strStr()
视频链接:帮你把KMP算法学个通透!(理论篇)
KMP算法(理论)
KMP算法(Knuth-Morris-Pratt 算法)是一个著名的字符串匹配算法。
在当前对文本串和模式串检索的过程中,若出现了不匹配,如何充分利用已经匹配的部分。
然后需要搞懂以下几个概念:
前缀、后缀,最长相等前后缀、前缀表、next数组。
- 前缀:包含首字母,不包含尾字母的所有子串,都被称为前缀
- 后缀:包含尾字母,不包含首字母的所有子串,都被称为后缀
- 最长相等前后缀:是对一个字符串而言,最长的、相等的、前缀和后缀。比如说aabaa的最长相等前后缀就是2,aabaaf最长相等前后缀就是0
- 前缀表:所有前缀和整个字符串的最长相等前后缀组成的表,一般是一个序列[0, 1, 0, 1, 2, 0]
- 使用前缀表的匹配过程
设文本串txt = aabaabaaf、模式串pat = aabaaf。前缀表是[0, 1, 0, 1, 2, 0],如果遇到不匹配,也就是说遍历到f,我们就找不包含f的前面那个子串的最长相等前后缀,是2。也就意味着,这里有一个后缀aa,前面也有一个与其相等的前缀aa。我们就找到与其相等的前缀的后面一个字符开始匹配。其实前缀的后面的那个字符的下标正好就是前缀的长度。
- next数组:其实就是存放前缀表的。
具体例子可以看上文推荐的视频。
KMP算法(代码)
构造next数组的伪代码:
void getNext(next, s)
{//初始化next数组和各个变量//j指向前缀末尾位置,同时j还指向了模式串冲突处前面子串的最长相等前后缀的长度。i指向后缀末尾位置//前缀一开始从模式串最前面的位置开始j = 0; next[0] = 0; //next[0] = 0是因为刚开始只有一个字母a,最长相等前后缀可不就是0//以上完成了初始化,至于i的初始化是一个循环遍历的过程。for (i = 1; i < s.szie();i++){//处理前后缀不相同的情况,也就是前缀末尾和后缀末尾不匹配的时候,j应该向前会退//而且j要会退到前一位置所对应的next数组的值,也就是next[j-1]的值。//为什么要这么跳呢,就是由于之前我们将的KMP的匹配流程里就是这么跳的,所以在这里//遵循循环不变量,也这么跳s[i] != s[j];while (j > 0 && s[i] != s[j]) j = next[j-1];//这里千万不能写成if,而是while。因为我们这里是一个连续回退的过程//处理前后缀相同的情况if (s[i] == s[j]) j++;//更新next数组的值next[i] = j; }
}
C++代码
前缀表(不减一)的C++代码实现:
class Solution {
public:void getNext(int* next, const string& s) {int j = 0;next[0] = 0;for(int i = 1; i < s.size(); i++) {while (j > 0 && s[i] != s[j]) {j = next[j - 1];}if (s[i] == s[j]) {j++;}next[i] = j;}}int strStr(string haystack, string needle) {if (needle.size() == 0) {return 0;}int next[needle.size()];getNext(next, needle);int j = 0;for (int i = 0; i < haystack.size(); i++) {while(j > 0 && haystack[i] != needle[j]) {j = next[j - 1];}if (haystack[i] == needle[j]) {j++;}if (j == needle.size() ) {return (i - needle.size() + 1);}}return -1;}
};
459.重复的子字符串
力扣题目链接
文字链接:459.重复的子字符串
视频链接:字符串这么玩,可有点难度! | LeetCode:459.重复的子字符串
暴力解法
直观的暴力解法:
枚举所有子串,然后去判断能不能构成这个字符串。
伪代码如下:
//一个for循环去获取子串的结束位置,然后继续里面的一个for循环就是拿子串去跟主串比较
for (搜索子串)for(子串去比较主串)//这里最有最有疑问的地方就是为什么一个for循环就能获取所有子串
//一般来说要两个for循环,一个用来获取子串的开始位置,另一个for循环用来获取结束位置//但其实这样是没有必要的
//我们默认这个子串是从最前面的元素开始的。所以一个for循环获取子串的终止位置就行了。
//而且遍历的时候 都不用遍历结束,只需要遍历到中间位置,因为子串结束位置大于中间位置的话,一定不能重复组成字符串。
移动匹配
其实按照题目的说法,如果这个字符串可以由重复子串构成,那么它前半部分和后半部分肯定是想定的(不过不一定非得从中间劈开的相等)
那么如果这是个重复的字符串,那么我们从后面再重复加一遍,变成s+s,那么这个字符串中也一定是包含了一个新的s,比如s=abcabc,s+s = abc|abcabc|abc,这里就出现了一个新s。但是我们在拼接之后一定要删除首尾字母,以免搜索过程中搜到我们原来的s和后来加的s,如果这样还能找到一个s,那么说明该字符串由重复子串组成。
C++代码如下:
class Solution {
public:bool repeatedSubstringPattern(string s) {string t = s + s;t.erase(t.begin()); t.erase(t.end() - 1); // 掐头去尾if (t.find(s) != std::string::npos) return true; // rreturn false;}
};
//需要注意的是,这里的t.find()其实就是用KMP算法来实现的,找某个字符串中是否包含该字符串
KMP解法
开篇一个结论:
如果字符串s = abababab
如果这个字符串是由重复子串组成的,那么它的最小重复单位,就是它的最长相等前后缀不包含的那个子串,就是它的最小重复子串。
具体讲解属实不好表达,建议直接去看视频:视频链接:字符串这么玩,可有点难度! | LeetCode:459.重复的子字符串
等二刷的时候看能不能搞清楚算了。
C++ 代码如下:
class Solution {
public:void getNext (int* next, const string& s){next[0] = 0;int j = 0;for(int i = 1;i < s.size(); i++){while(j > 0 && s[i] != s[j]) {j = next[j - 1];}if(s[i] == s[j]) {j++;}next[i] = j;}}bool repeatedSubstringPattern (string s) {if (s.size() == 0) {return false;}int next[s.size()];getNext(next, s);int len = s.size();if (next[len - 1] != 0 && len % (len - (next[len - 1] )) == 0) {return true;}return false;}
};
相关文章:
代码随想录笔记|C++数据结构与算法学习笔记-字符串(二)|28. 实现 strStr()、459.重复的子字符串、KMP算法
文章目录 卡码网.右旋字符串28. 实现 strStr()KMP算法(理论)KMP算法(代码)C代码 459.重复的子字符串暴力解法移动匹配KMP解法 卡码网.右旋字符串 卡码网题目链接 略 28. 实现 strStr() 力扣题目链接 文字链接:28. 实现 strStr() 视频链接:帮你把KMP算法…...
【复杂网络建模】——建模工具Matlab入门
目录 一、认识MATLAB 二、认识工具箱 三、基本操作和函数 3.1 算术操作符 3.2 数学函数 3.3 矩阵操作 3.4 索引和切片 3.5 逻辑操作 3.6 控制流程 3.7 数据输入输出 四、变量和数据类型 4.1 数值类型 4.2 整型 4.3 复数 4.4 字符串 4.5 逻辑类型 4.6 结构体&a…...
JVM面试篇
面试篇就是复习前面学的 什么是JVM 1.定义:JVM指的是Java虚拟机,本质是一个运行在计算机上的程序 2.作用:为了支持Java中Write Once ,Run Anywhere 编写一次 到处运行的跨平台特性 功能: 1.解释和运行 2.内存管理…...
openEuler 22.03(华为欧拉)一键安装 Oracle 19C RAC(19.22) 数据库
前言 Oracle 一键安装脚本,演示 openEuler 22.03 一键安装 Oracle 19C RAC 过程(全程无需人工干预):(脚本包括 ORALCE PSU/OJVM 等补丁自动安装) ⭐️ 脚本下载地址:Shell脚本安装Oracle数据库…...
蓝桥杯刷题记录之数字王国之军训排队
记录 卡了半天,check函数中的temp % ele 0写成了ele % temp 0就挺无语的 思路 这个晚上在补 代码 import java.util.*; public class Main{static List<List<Integer>> que new ArrayList<>();static int MIN Integer.MAX_VALUE;static i…...
Go语言学习Day1:什么是Go?
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 1、走近Go①Go语言的Logo②Go语言的创始人③Go语…...
C语言内存函数之 memcmp函数
memcmp函数的记忆:mem表示内存,单位是字节,表示以单位字节来进行操作;头文件是string.h,cmp是compare的缩写,表示比较。总的意思就是在规定的内存下以字节为单位一个字节一个字节的进行比较。 memcmp函数的…...
3. C++ 常见的段错误及对策
常见的 C/C 段错误及对策 一、指针没有指向一块合法的内存 定义了指针变量,但是没有为指针分配内存,即指针没有指向一块合法的内存。这里举几个比较隐蔽的例子。 结构体成员指针未初始化;没有为结构体指针分配足够的内存;函数的…...
推荐的Kubernetes 学习资料
官方文档: Kubernetes 官方文档:https://kubernetes.io/docs/Kubernetes 教程:https://kubernetes.io/docs/tutorials/ 书籍: Kubernetes in Action,Marko Luksa 著Kubernetes Up and Running,Kelsey Hi…...
MySQL之索引与事务
一 索引的概念 一种帮助系统查找信息的数据 数据库索引 是一个排序的列表,存储着索引值和这个值所对应的物理地址无须对整个表进行扫描,通过物理地 址就可以找到所需数据是表中一列或者若干列值排序的方法 需要额外的磁盘空间 索引的作用 1 数据库…...
Linux的基本使用
1.Linux的背景 1.1什么Linux Linux是⼀个操作系统.和Windows是"并列"的关系. 1.2Linux系统的优势 1. 开源(意味着免费,便宜) 2. 稳定(Linux可以运⾏很多年,都不会发⽣重⼤问题) 3. 安全(Linux只有管理员或者特定⽤⼾才能访问Linux内核) 4. ⾃由(不会被强加商业产品和…...
亚信安慧AntDB全景观察:数据库领域的创新者
随着大数据时代的到来,对数据库的需求愈发强烈。在这一背景下,国产数据库逐渐崭露头角,亚信安慧AntDB作为重要的代表产品之一正积极参与到激烈的市场竞争中。亚信安慧AntDB不仅追求技术的革新和突破,同时也致力于满足用户日益增长…...
Linux 系统是如何收发⽹络包的
Linux 系统是如何收发⽹络包的? ⽹络模型 为了使得多种设备能通过⽹络相互通信,和为了解决各种不同设备在⽹络互联中的兼容性问题,国际标准化组织制定了开放式系统互联通信参考模型(Open System Interconnection Reference Mode…...
飞跃前端瓶颈:技术进阶指南精华篇
引言: 在互联网的快车道上,前端技术日新月异。对于前端工程师而言,技术水平达到一定高度后,往往会遭遇成长的天花板。本文将探讨如何识别并突破这些技术瓶颈,分享实用的进阶策略和实践案例。 一、技术等级概览…...
Jenkins安装 Linux 更换镜像 安装插件
Jenkins安装 Linux 更换镜像 安装插件 前言 下面叙述了三种jenkins安装的方式,jenkins安装之前必须有java环境因为他是java写的… yum安装只能安装最新版本的jenkins,但是jenkins是java写的所以他强依赖java版本,当你的服务器的java版本与jenkins版本冲突时还需要给jenkins重…...
(一)基于IDEA的JAVA基础1
Java是一门面向对象的编程语言,不仅吸收了C语言的各种优点,还摒弃了C里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论࿰…...
FPGA开源项目分享——基于FPGA加速的热扩散模拟器
导语 今天继续分享康奈尔大学FPGA课程ECE 5760的典型案例——基于FPGA加速的热扩散模拟器。 (更多其他案例请参考网站: Final Projects ECE 5760) 1. 项目概述 项目网址 https://people.ece.cornell.edu/land/courses/ece5760/FinalProje…...
【ARM 嵌入式 C 入门及渐进 12 --寄存器位清0和置位函数实现】
文章目录 寄存器位清0和置位函数实现示例使用方式注意事项 寄存器位清0和置位函数实现 在 C 语言中,可以使用宏定义来创建用于清除(清零)或设置(置一)32位地址中特定位的函数。以下是两个宏定义的示例: #…...
Java实现10万,并发去重,优雅地处理重复请求!
对于一些用户请求,在某些情况下是可能重复发送的,如果是查询类操作并无大碍,但其中有些是涉及写入操作的,一旦重复了,可能会导致很严重的后果,例如交易的接口如果重复请求可能会重复下单。 重复的场景有可…...
《深入解析 C#》—— C# 3 部分
文章目录 第三章 C#3:LINQ及相关特性3.1 自动实现属性(*)3.2 隐式类型 var(*)3.3 对象和集合初始化3.3.1 对象初始化器3.3.2 集合初始化器 3.4 匿名类型3.4.1 基本语法和行为3.4.2 编译器生成类型3.4.3 匿名类型的局限…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
