突破编程_C++_字符串算法(判断字符串是否包含)

1 算法题 :判断一个字符串是否包含另一个字符串的所有字符(不一定连续)

1.1 题目含义

判断一个字符串(称为“主字符串”或“大字符串”)是否包含另一个字符串(称为“子字符串”或“小字符串”)的所有字符,且不论这些字符在主字符串中的顺序和连续性。换句话说,我们要确认子字符串的每一个字符至少在主字符串中出现一次。

1.2 示例

示例 1:
输入:

  • 主字符串: “abcdefghijklmnopqrstuvwxyz”
  • 子字符串: “abcde”

输出: true
解释: 主字符串包含子字符串的所有字符。

示例 2:
输入:

  • 主字符串: “mississippi”
  • 子字符串: “missip”

输出: true
解释: 尽管 “missip” 在主字符串中不是连续的,但主字符串包含子字符串的所有字符。

示例 3:
输入:

  • 主字符串: “abcdefg”
  • 子字符串: “defghijklmnop”

输出: false
解释: 主字符串不包含子字符串的所有字符,因为 “hijklmnop” 中的字符在主字符串中没有出现。

2 解题思路

解题思路如下:

(1)初始化哈希表:
在 C++ 中,我们可以使用std::unordered_map来作为哈希表。首先,遍历子字符串,对于每个字符,我们在unordered_map中增加其计数。

(2)遍历主字符串并更新哈希表:
然后,遍历主字符串。对于主字符串中的每个字符,我们检查它是否在unordered_map中。如果在,则将其对应的计数减一。如果不在,说明主字符串中缺少该字符,因此可以立即返回false。

(3)检查哈希表:
在遍历完主字符串后,我们检查 unordered_map 中所有字符的计数是否都已经归零。如果所有计数都为零,说明主字符串包含了子字符串的所有字符,返回 true;如果存在任何非零计数,说明主字符串缺少某些字符,返回 false。

(4)返回结果:
根据unordered_map的状态,返回相应的布尔值。

3 算法实现代码

3.1 使用哈希表

如下为算法实现代码:

#include <iostream>  
#include <unordered_map>  
#include <string>  class Solution
{
public:bool isContainsAllCharacters(const std::string& mainString, const std::string& subString) {// 初始化哈希表  std::unordered_map<char, int> charCounts;for (char c : subString) {charCounts[c]++;}// 遍历主字符串并更新哈希表  for (char c : mainString) {if (charCounts.find(c) != charCounts.end()) {charCounts[c]--;if (charCounts[c] == 0) {// 如果字符的计数减到0,从哈希表中删除该字符  charCounts.erase(c);}}}// 检查哈希表  return charCounts.empty(); // 如果哈希表为空,说明所有字符都被找到了  }
};

在 isContainsAllCharacters 成员函数中,首先使用std::unordered_map<char, int>创建了一个名为charCounts的哈希表。这个哈希表将存储 subString中 每个字符及其出现的次数(遍历 subString 中的每个字符 c,并在 charCounts 中增加该字符的计数。如果字符 c 在 charCounts 中不存在,它会被插入到哈希表中并设置计数为 1;如果它已经存在,则计数增加 1)。

接下来,使用 find 方法来检查字符 c 是否存在于 charCounts 中。如果字符 c 在 charCounts 中存在,将其计数减 1。如果减1后计数变为 0,说明 mainString 中的这个字符与 subString 中的字符数量相匹配,可以从 charCounts中 删除这个字符。

最后,如果哈希表为空,说明 mainString 包含了 subString 中的所有字符,因为所有在 subString 中出现的字符都已经在 mainString 中被匹配并从哈希表中删除了。如果哈希表不为空,则意味着至少有一个 subString 中的字符在 mainString 中没有出现。

调用上面的算法,并得到输出:

int main() 
{Solution solution;std::string mainString = "abcdefghijklmnopqrstuvwxyz";std::string subString = "abcde";std::cout << "Does \"" << mainString << "\" contain all characters of \"" << subString << "\"? "<< (solution.isContainsAllCharacters(mainString, subString) ? "Yes" : "No") << std::endl;mainString = "mississippi";subString = "missip";std::cout << "Does \"" << mainString << "\" contain all characters of \"" << subString << "\"? "<< (solution.isContainsAllCharacters(mainString, subString) ? "Yes" : "No") << std::endl;mainString = "abcdefg";subString = "defghijklmnop";std::cout << "Does \"" << mainString << "\" contain all characters of \"" << subString << "\"? "<< (solution.isContainsAllCharacters(mainString, subString) ? "Yes" : "No") << std::endl;return 0;
}

上面代码的输出为:

Does "abcdefghijklmnopqrstuvwxyz" contain all characters of "abcde"? Yes
Does "mississippi" contain all characters of "missip"? Yes
Does "abcdefg" contain all characters of "defghijklmnop"? No

3.2 使用排序和比较的方法

这种方法的思路是,如果主字符串包含子字符串的所有字符,那么对两个字符串进行排序后,排序后的子字符串应该是排序后的主字符串的一个子序列。该方法的优点是它不需要使用额外的数据结构来记录字符的出现次数,而是通过比较排序后的字符串来直接得出结论。然而,它的缺点是需要对字符串进行排序,这可能会增加一些计算复杂度。
如下为算法实现代码:

#include <iostream>  
#include <cctype>  
#include <string>  
#include <algorithm> // 用于std::sortclass Solution 
{
public:bool isContainsAllCharacters(const std::string& mainString, const std::string& subString) {// 对两个字符串进行排序std::string sorted_main = mainString;std::string sorted_sub = subString;std::sort(sorted_main.begin(), sorted_main.end());std::sort(sorted_sub.begin(), sorted_sub.end());// 使用双指针法检查 sorted_sub 是否是 sorted_main 的子序列  int i = 0, j = 0;while (i < sorted_sub.length() && j < sorted_main.length()) {if (sorted_sub[i] == sorted_main[j]) {i++; // 移动到 sorted_sub 的下一个字符  }j++; // 移动到 sorted_main 的下一个字符  }// 如果 sorted_sub 的所有字符都在 sorted_main 中找到,则 sorted_sub 是 sorted_main 的子序列  return  sorted_sub.length() == i;}
};

在这个实现中,首先使用 std::sort 函数对这两个字符串进行排序。排序后,sorted_main 和 sorted_sub 分别包含与 mainString 和 subString 相同但已排序的字符。

然后,使用双指针法检查 sorted_sub 是否是 sorted_main 的子序列(注意:无论是否找到匹配的字符,都将 j 增加 1,以继续检查 sorted_main 的下一个字符)。

接着,判断 sorted_sub 的所有字符是否都在 sorted_main 中找到(如果 sorted_sub 的所有字符都在 sorted_main 中找到,那么 i 的值应该等于 sorted_sub 的长度)。

4 测试用例

以下是针对上面算法的测试用例:

(1)基础测试用例:
输入:

  • 主字符串: “abcdefg”
  • 子字符串: “bcd”

输出: true
解释: 主字符串包含子字符串的所有字符。

(2)包含所有字符但顺序不同:
输入:

  • 主字符串: “bacdefg”
  • 子字符串: “abc”

输出: true
解释: 虽然字符顺序不同,但主字符串包含子字符串的所有字符符。

(3)缺少一个字符:
输入:

  • 主字符串: “abdefg”
  • 子字符串: “abc”

输出: false
解释: 主字符串缺少子字符串中的一个字符 ‘c’。

(4)包含重复字符:
输入:

  • 主字符串: “aabbbccc”
  • 子字符串: “abc”

输出: true
解释: 即使主字符串中的字符有重复,但它仍然包含子字符串中的所有字符。

(5)子字符串是主字符串的前缀:
输入:

  • 主字符串: “abcdefg”
  • 子字符串: “abc”

输出: true
解释: 子字符串是主字符串的前缀,因此主字符串必然包含子字符串中的所有字符。

这些测试用例涵盖了不同的场景,从基础情况到边缘情况,有助于验证代码的正确性和健壮性。

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

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

相关文章

代码随想录算法训练营第31天—贪心算法05 | ● 435. 无重叠区间 ● *763.划分字母区间 ● *56. 合并区间

435. 无重叠区间 https://programmercarl.com/0435.%E6%97%A0%E9%87%8D%E5%8F%A0%E5%8C%BA%E9%97%B4.html 考点 贪心算法重叠区间 我的思路 先按照区间左坐标进行排序&#xff0c;方便后续处理进行for循环&#xff0c;循环范围是0到倒数第二个元素如果当前区间和下一区间重叠…

在Linux以命令行方式(静默方式/非图形化方式)安装MATLAB(正版)

1.根据教程&#xff0c;下载windows版本matlab&#xff0c;打开图形化界面&#xff0c;选择linux版本的只下载不安装 2.获取安装文件夹 3.获取许可证 4.安装 &#xff08;1&#xff09;跳过引用文章的2.2章节 &#xff08;2&#xff09;本文的安装文件夹代替引用文章的解压IS…

Java进阶(锁)——锁的升级,synchronized与lock锁区别

目录 引出Java中锁升级synchronized与lock锁区别 缓存三兄弟&#xff1a;缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 Java进阶&#xff08;锁&#xff09;——锁的升级&#xff0c;synchronized与lock锁区别 Java中锁升级 看一段代码&#xff1a; public class…

Fastwhisper + Pyannote 实现 ASR + 说话者识别

文章目录 前言一、faster-whisper简单介绍二、pyannote.audio介绍三、faster-whisper pyannote.audio 实现语者识别四、多说几句 前言 最近在研究ASR相关的业务&#xff0c;也是调研了不少模型&#xff0c;踩了不少坑&#xff0c;ASR这块&#xff0c;目前中文普通话效果最好的…

Scrapy与分布式开发(1.1):课程导学

Scrapy与分布式开发&#xff1a;从入门到精通&#xff0c;打造高效爬虫系统 课程大纲 在这个专栏中&#xff0c;我们将一起探索Scrapy框架的魅力&#xff0c;以及如何通过Scrapy-Redis实现分布式爬虫的开发。在本课程导学中&#xff0c;我们将为您简要介绍课程的学习目标、内容…

Verilog Coding Styles For Improved Simulation Efficiency论文学习记录

原文基于Verilog-XL仿真器&#xff0c;测试了以下几种方式对仿真效率的影响。 1. 使用 Case 语句而不是 if / else if 语句 八选一多路选择器 case 实现效率比 if / else if 提升 6% 。 2. 如果可以尽量不使用 begin end 语句 使用 begin end 的 ff 触发器比不使用 begin end …

初学者学习51还是STM32

初学者学习51还是STM32 在嵌入式系统领域&#xff0c;51和STM32是两种常见的单片机架构。对于初学者来说&#xff0c;选择学习哪种架构可能会成为一个难题。本文将对初学者学习51和STM32进行比较&#xff0c;以帮助读者做出明智的选择。 1. 51架构 51架构是指Intel 8051系列…

深度相机xyz点云文件三维坐标和jpg图像文件二维坐标的相互变换函数

深度相机同时拍摄xyz点云文件和jpg图像文件。xyz文件里面包含三维坐标[x,y,z]和jpg图像文件包含二维坐标[x&#xff0c;y],但是不能直接进行变换&#xff0c;需要一定的步骤来推演。 下面函数是通过box二维框[xmin, ymin, xmax, ymax, _, _ ]去截取xyz文件中对应box里面的点云…

MyCAT学习——在openEuler22.03中安装MyCAT2(网盘下载版)

准备工作 因为MyCAT 2基于JDK 1.8开发。也需要在虚拟机中安装JDK&#xff08;JDK官网就能下载&#xff0c;我这提供一个捷径&#xff09; jdk-8u401-linux-x64.rpmhttps://pan.baidu.com/s/1ywcDsxYOmfZONpmH9oDjfw?pwdrhel下载对应的tar安装包,以及对应的jar包 安装程序包…

九州金榜|孩子厌学要怎么办?

孩子从小学到初中再到高中&#xff0c;孩子出现厌学情绪很正常&#xff0c;但是孩子出现厌学情绪后&#xff0c;就必然会影响到孩子学习成绩&#xff0c;孩子产生厌学情绪的原因有哪些呢&#xff1f;只有找准孩子厌学原因才能去帮助孩子怎样去克服孩子厌学情绪&#xff0c;下面…

ajax请求servlet成功但接收不到返回数据问题

ajax请求servlet成功但接收不到返回数据问题 javaweb初学者&#xff0c;最近老师布置的课设&#xff0c;所有功能都完成了&#xff0c;唯独ajax与servlet交互出现问题&#xff0c;无论怎么调试都收不到数据 查询两天无果&#xff0c;刚才无意间看到 Crabime前辈的文章才恍然大…

深入解析YOLO:实时目标检测技术的革命者

深入解析YOLO&#xff1a;实时目标检测技术的革命者 目标检测作为计算机视觉领域的一个核心任务&#xff0c;一直以来都是研究的热点。而YOLO&#xff08;You Only Look Once&#xff09;技术作为其中的杰出代表&#xff0c;以其独特的处理方式和卓越的性能&#xff0c;成为了…

day34贪心算法 part03

1005. K 次取反后最大化的数组和 简单 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数组&#xff1a; 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。 以这种方式修改数组后&#xff0c;返回数…

力扣栈队列篇

以下思路来自代码随想录以及官方题解。 文章目录 232.用栈实现队列225.用队列实现栈20.有效的括号1047.删除字符串中所有相邻重复项150.逆波兰表达式求值347.前K个高频元素 232.用栈实现队列 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff…

OSError: [WinError 1455] 页面文件太小,无法完成操作。

[问题描述]&#xff1a;OSError: [WinError 1455] 页面文件太小&#xff0c;无法完成操作。 原因1&#xff1a;线程数太大 方法&#xff1a;改小线程&#xff08;workers&#xff09;数。 原因2&#xff1a;虚拟内存太小或为0&#xff0c;调大虚拟内存。 方法&#xff1a;右键…

mysql索引过长Specialed key was too long的解决方法

在创建要给表的时候遇到一个有意思的问题&#xff0c;提示Specified key was too long; max key length is 767 bytes&#xff0c;从描述上来看&#xff0c;是Key太长&#xff0c;超过了指定的 767字节限制。通常出现在尝试创建一个过长的唯一键&#xff08;UNIQUE KEY&#xf…

Vue.js 实用技巧:深入理解 Vue.mixin

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

uniapp真机运行的时候显示同步资源失败,未得到同步资源的授权,请停止运行后重新运行,并注意手机上的授权提示

1、问题 在添加清单文件之前&#xff0c;项目运行都是好好的&#xff0c;添加了清单项目以后&#xff0c;基座一打就报这个错&#xff0c;并且手机在安装基座的时候会提示解析包时失败&#xff0c; 2、解决方案 打开我的清单文件&#xff0c;我发现我和官网写的清单文件不一…

华为OD机试“HJ2计算某字符出现次数”不区分大小写Java编程解答

描述 写出一个程序&#xff0c;接受一个由字母、数字和空格组成的字符串&#xff0c;和一个字符&#xff0c;然后输出输入字符串中该字符的出现次数。&#xff08;不区分大小写字母&#xff09; 数据范围&#xff1a; 1≤n≤1000 输入描述&#xff1a; 第一行输入一个由字…

【Linux进程间通信】共享内存

【Linux进程间通信】共享内存 目录 【Linux进程间通信】共享内存system V共享内存共享内存示意图共享内存的数据结构共享内存函数将共享内存挂接到对应的进程将共享内存取消挂接释放共享内存 共享内存的特性共享内存扩展共享内存配合管道进行使用 作者&#xff1a;爱写代码的刚…