代码随想录笔记|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;}
};

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

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

相关文章

JAVA刷题 字符操作串各种方法总结(随时更新)

写在前面 JAVA万能头&#xff1a; import java.io.*; import java.util.*;JAVA字符串方法参数操作 谨记【左闭右开】原则 一、substring()方法 两个参数&#xff1a; 字符串.substring(参数1&#xff0c;参数2); 参数1&#xff1a;字符串截取的起始下标&#xff0c;非负的整…

CentOS yum安装MongoDB的详细教程

一、准备工作 打开终端或SSH会话&#xff0c;并使用root或具有管理员权限的用户登录到CentOS服务器。 二、添加MongoDB的源 执行以下命令添加MongoDB的存储库 sudo vi /etc/yum.repos.d/mongodb-org.repo 在编辑器中&#xff0c;复制并粘贴以下内容 [mongodb-org-6.0] name…

什么是UI设计?适合做UI设计的软件有哪些?

人们常说 UI 和 UI 设计&#xff0c;但到底什么是 UI 设计&#xff1f;UI 设计的原则是什么&#xff1f;实际上 “UI" 也就是 User Interface&#xff0c;它是用户界面的缩写。一般指用户操作界面&#xff0c;即软件程序、网站或设备的图形部分&#xff0c;用户与之互动。…

GEE学习——初学者如何下载指定区域的Sentinel-2影像

简介 初学者如何下载指定区域的Sentinel-2影像? 初学者可以按照以下步骤利用Google Earth Engine(GEE)下载指定区域的Sentinel-2影像: 登录GEE账号并打开代码编辑器。代码编辑器位于GEE主页左上角的"Code Editor"按钮。 在代码编辑器中,点击左上角的"App…

自定义高亮文字的textview,匹配关键字词高亮,匹配可拆分的字词高亮

自定义高亮文字的textview&#xff0c;匹配关键字词高亮&#xff0c;匹配可拆分的字词高亮 import android.graphics.Color; import android.text.SpannableString; import android.text.Spanned; import android.text.style.ForegroundColorSpan;import java.util.regex.Match…

MyBatis3源码深度解析(十九)MyBatis日志实现

文章目录 前言第七章 MyBatis日志实现7.1 Java日志体系7.1.1 常用日志框架7.1.2 Java日志发展史7.1.3 日志接口与日志实现的绑定 7.2 MyBatis日志实现7.2.1 Log接口7.2.2 LogFactory工厂7.2.3 MyBatis日志自动查找7.2.4 MyBatis日志类型配置 7.3 小结 前言 日志是Java应用中必…

蓝桥算法练习系统—卡勒沃夫之弱水路三千(提高型)(拓扑排序)

问题描述 锦瑟年华谁与度 莫问情归处 只影向斜阳 剑吼西风 欲把春留驻   天涯芳草无归路 回首花无数 解语自销魂 弱袂萦春 尘缘不相误   ......   在卡勒沃夫充满文学杀伤力的声音中&#xff0c;身处紫荆2号楼202B的四位远近高低各不同的室友纷纷回忆起了各自波澜起伏的过…

【合合TextIn】深度解析智能文档处理技术与应用

目录 一、智能文档处理介绍 二、文档格式解析 三、图像增强技术解析 四、传统文字识别OCR技术解析 五、深度学习OCR技术解析 六、深度学习版面分析技术解析 七、文档分类 八、信息抽取 九、系统集成&#xff1a;将IDP处理后的数据集成到企业系统 结论 一、智能文档处…

机器学习-06-无监督算法-01-划分聚类Kmeans算法

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中无监督算法&#xff0c;包括划分聚类等。 参考 数据分析实战 | K-means算法——蛋白质消费特征分析 欧洲48国英文名称的来龙去脉及其国旗动画 Kmeans在线动态演示 本门课程的目标 完成一个特定行业的…

如何与手机共享笔记本电脑的互联网?这里提供详细步骤

这篇文章介绍了如何通过将手机变成Wi-Fi热点来与手机共享笔记本电脑的互联网连接。 如何共享笔记本电脑的互联网连接 你可以通过Wi-Fi或有线共享笔记本电脑的数据连接,具体取决于你的设置。 Windows Windows允许你通过ICS共享你的互联网连接。ICS,或称互联网连接共享,是W…

ARM Coresight 系列文章 11.1 -- CoreSight Cortex-M33 CTI 详细介绍】

请阅读【ARM Coresight SoC-400/SoC-600 专栏导读】 文章目录 CTI 的工作原理CTI 主要特点CTI的使用场景CTI 的工作原理 CTI 允许不同的调试和追踪组件之间基于特定事件进行交互。例如,当一个断点被命中时,CTI 可以用来触发内存的追踪捕捉或者外部仪器的行为,反之亦然。这种…

java项目的文件结构

java项目的文件结构 commomconfigcontorlledtoentity 在一个典型的 Java 项目中&#xff0c;通常会遵循一定的文件结构约定&#xff0c; 以下是一个常见的 Java 项目文件结构示例&#xff1a;/YourProjectName/src/main/java/com/example/projectMain.java/resourcesconfig.pro…

【华大 HC32L110】调用`printf`和串口接收中断的冲突问题解决

华大单片机 HC32L110调用printf和串口接收中断的冲突问题解决&#xff0c;经过查找是官方库 去使能了 串口的接收功能&#xff0c;记录解决问题的过程 目录 1.硬件MCU资料2. printf和串口接收中断的冲突解决3.重新封装 fputc 函数4.查找问题&#xff0c;发现是官方库配置有误5.…

无线局域网——wlan

目录 一.wlan的含义和发展 二.wlan技术带来的挑战 1.企业办公场景多样 2.位置速度的要求 3.安全的要求 4.规范的挑战 三.家庭和企业不同的部署需求 1.胖AP模式组网 2.AC瘦AP模式组网 3.组网模式的不同 四.三层隧道转发实验 1.拓扑 2.AP上线 核心交换机vlan ​编辑…

AWS ECS安全更新及自动化应对方案

AWS发布了一些重要的安全补丁,旨在修复ECS中发现的一些漏洞和问题。这些更新涉及多个方面,包括服务配置、任务定义等。为了确保我们的应用程序和基础设施的安全性,我们有必要及时采纳这些更新。 在本文中,我将分享一段Python代码,它利用AWS SDK(Boto3)与ECS进行交互,自动强制为…

探索海外市场舆情:云手机助力企业赢得全球竞争

在全球化的趋势下&#xff0c;越来越多的企业将目光投向海外市场&#xff0c;迎接着无尽的商机与挑战。然而&#xff0c;随之而来的是境外市场舆情的复杂变化&#xff0c;对企业的声誉和发展带来了潜在风险。如何准确、及时地掌握境外市场的舆情动向&#xff0c;成为了企业必须…

Midjourney发布新特性风格参考

1. 引言 最近&#xff0c;Midjourney 推出了Style Reference V2.0 即功能更加强大的风格参考工具&#xff0c;该工具可以让大家参考其他图像的风格&#xff0c;生成与参考图像风格保持一致&#xff0c;与文本提示词语义内容保持一致的图像。它与图像提示类似&#xff0c;但是只…

上位机开发使用的编程语言多种多样,每种语言都有其独特的优缺点。

上位机开发所使用的编程语言多种多样&#xff0c;每一种语言都有其独特的优势和适用场景。目前&#xff0c;没有明确的、统一的“上位机编程语言排行榜”&#xff0c;因为编程语言的选择很大程度上取决于项目的具体需求、开发团队的技能和经验&#xff0c;以及语言的性能和易用…

Day03-数据库管理(事务管理,用户管理,MySQL8的部分新特性)

文章目录 Day03 数据库管理学习目标1. 事务管理1.1 事务的概念1.2 事务的特性1.3 语法1.4 事务的并发问题1.5 事务隔离级别1.6 设置和查看隔离级别 2 用户管理2.1 创建删除用户2.2 权限管理2.2.1 权限赋予的原则2.2.2 权限赋予2.2.3 权限回收2.2.4 登录管理 3. MySQL8的部分新特…

Java中的I/O讲解(超容易理解)(下篇)

如果想观看更多Java内容 可上我的个人主页关注我&#xff0c;地址子逸爱编程-CSDN博客https://blog.csdn.net/a15766649633?typeblog 使用工具 IntelliJ IDEA Community Edition 2023.1.4 使用语言 Java8 代码能力快速提升小方法&#xff0c;看完代码自己敲一遍&#xff0…