【C++】 string类:应用与实践

💞💞 前言

hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹
在这里插入图片描述

💥个人主页:大耳朵土土垚的博客
💥 所属专栏:C++入门至进阶
这里将会不定期更新有关C++的内容,希望大家多多点赞关注收藏💖💖

💥本篇博客将使用string类求解五个题目,包括题目链接,解题思路以及实现代码,题目中有关函数的理解和使用,也会挑出一些来介绍🥳🥳

目录

  • 💞💞 前言
    • ☑️找出字符串中第一个只出现一次的字符
    • ☑️字符串里面最后一个单词的长度
    • ☑️翻转字符串
    • ☑️字符串相加
    • ☑️字符串转整形数字
    • 结语

☑️找出字符串中第一个只出现一次的字符

✨✨题目链接点击跳转
在这里插入图片描述
解题思路

这里可以参考我们之前学习过的计数排序:
①先定义一个int数组,大小为26*sizeof(int),用来一一对应26个字母(小写),记录每个字母出现的次数;
②然后遍历题目中的字符串s,计算出每个字母的个数存放在之前定义的数组中;
③最后再通过遍历原字符串s找出第一次只出现一次的字符。

代码如下:

#include <iostream>
using namespace std;
#include<string>
int main()
{string s;   //原字符串cin>>s;int count[26] = {0} ; //开辟一个数组计数for(auto ch : s) //范围for遍历{count[ch-'a']++; //计数}for(auto ch : s)    //再次遍历找到第一个出现一次的字符{if(count[ch-'a'] == 1){cout<<ch;   //找到了打印该字符return 0;}}cout<<-1;   //没找到输出-1return 0;
}

这里遍历string类可以参考【C++】学习string类:字符操作的艺术这篇文章讲述的三种方法;

结果如下:
在这里插入图片描述

☑️字符串里面最后一个单词的长度

✨✨题目链接点击跳转
在这里插入图片描述
解题思路

①使用getline函数(后文有解析)获取一行字符串;
②使用rfind函数(使用方法在后文)从字符串末尾往前找到第一个空格,返回该空格的位置;
③使用size函数得到整个字符串长度,减去之前空格的位置再-1,得出最后一个单词的长度。

#include <iostream>
using namespace std;
#include<string>
int main()
{string s;getline(cin,s);   //获取一行字符串int pos = s.rfind(' ');//从后往前遍历找到空格的位置int length = s.size() - pos-1; //计算最后一个单词长度cout<<length;  //打印长度
}

结果如下:
在这里插入图片描述

🥳🥳getline使用方法

  • getline是C++中用于从输入流中读取一行文本的函数。它通常与std::cin结合使用。

示例如下:

#include <iostream>
#include <string>int main() {std::string line;std::cout << "请输入一行文本:";std::getline(std::cin, line);std::cout << "你输入的内容是:" << line << std::endl;return 0;
}

在上面的代码中,std::getline(std::cin, line)将从标准输入流(std::cin)中读取一行文本,并将其存储到名为line的字符串变量中。然后,我们可以使用std::cout打印出用户输入的内容。

  • getline函数还可以接受可选的第三个参数delim,用于指定行分隔符。默认情况下,行分隔符为换行符(\n)。可以将其修改为其他字符,如:
std::getline(std::cin, line, ';');

这将使用分号作为行分隔符

🥳🥳rfind函数使用方法:

  • rfind是C++中的字符串成员函数,用于从字符串的末尾开始查找指定的子字符串,返回最后一次出现的位置。如果未找到子字符串,则返回std::string::npos。

示例如下:

#include <iostream>
#include <string>int main() {std::string str = "Hello world, hello C++";std::size_t found = str.rfind("hello");if (found != std::string::npos) {std::cout << "子字符串在位置 " << found << " 处找到了" << std::endl;} else {std::cout << "未找到子字符串" << std::endl;}return 0;
}

结果如下:
在这里插入图片描述

在上面的代码中,rfind函数从字符串的末尾开始搜索子字符串hello。如果找到了,则返回子字符串的起始位置。如果未找到,则返回std::string::npos。

  • rfind函数还可以接受第二个参数pos,用于指定搜索的起始位置。可以通过调整起始位置来实现在字符串的特定部分进行查找。
    示例如下:
std::size_t found = str.rfind("hello", 10);

这将从字符串的前10个字符开始向后搜索子字符串hello。

  • 需要注意的是,rfind函数返回的位置是从字符串的起始位置(下标为0)开始计算的。

☑️翻转字符串

✨✨题目链接点击跳转
在这里插入图片描述
解题思路

使用左右指针法:
①定义左右下标,当left < right时,交换它们对应的内容;
②直到left >= right 反转完成。

代码如下:

class Solution {
public:void reverseString(vector<char>& s) {//定义左右下标int left = 0;int right = s.size()-1;char tmp = '0';while(left < right)	//左右交换{tmp = s[right];s[right] = s[left];s[left] = tmp;left++;right--;}}
};

结果如下:
在这里插入图片描述

☑️字符串相加

✨✨题目链接点击跳转
在这里插入图片描述
解题思路

采用从后往前遍历两个数组,依次相加的方法,注意要进位:
①定义两个整型分别初始化为两个字符串最后一个字符下标;
②根据下标依次相加,定义整型flag记录进位,如果相加的和大于10,flag就标为1;
④将相加后的和存放在string类中(注意这里直接尾插即可,后面我们再翻转字符串);

代码如下:

class Solution {
public:string addStrings(string num1, string num2) {string num;	//用来存放相加后的字符//定义两个整型分别初始化为两个字符串最后一个字符下标;int end1 = num1.size() -1;int end2 = num2.size() -1;int n = 0;int flag = 0;//记录进位while(end1>=0 || end2 >=0){int n1 = end1 >= 0 ? num1[end1]-'0' :0;	//这里如果end1小于0,那么就将n1赋值为0;end1>=0,说明字符串num1中还有值没加,就将n1赋值为num1[end1] - '0'int n2 = end2 >= 0 ? num2[end2]-'0' :0;	//同上n = n1+n2;	//两数相加if(flag == 1)	//如果有进位,则n++;{n++;}num+=(n%10+'0');	//将和n转成字符存放到num中if(n >= 10){flag = 1;//表示要进一位}else{flag = 0;}end1--;end2--;}//最后如果还存在进位,就需要再+1if(flag == 1){num+='1';}//逆置reverse(num.begin(),num.end());return num;}};

这里有几个关键点:
①当end1<0时,end2>=0;也就是出现一个string中的字符加完了,另一个还剩,这时我们就可以借助三目运算符 int n1 = end1 >= 0 ? num1[end1]-'0' :0;将n1赋值为0,继续和n2相加即可,直到end2<0;
②当全部加完后,还要检查一下进位flag是否为1,如果为1,那么num还需要+1
例如:num1 = “11” , num2 = “999” 时,就需要再+1;
③最后不要忘了反转字符串,如果使用头插就不需要反转字符串,但是头插时间复杂度为O(n^2),效率太低。

结果如下:
在这里插入图片描述

☑️字符串转整形数字

✨✨题目链接点击跳转
在这里插入图片描述
解题思路

这里要注意看懂题目:
①前导如果有字符那么除了‘±’就是空格,一旦有空格后面一定是连续的空格,所以我们要使用while循环跳过前面的空格直到出现‘±’或者数字;
②还需要通过跳过前导空格后第一个字符是否为-,来判断正负,我们可以使用bool类型sign来判断;
③如果跳过前导空格后第一个字符为‘+/-’,就跳过第一个(下标i++)从第二个字符开始求和;如果是数字则直接从跳过空格后的第一个字符开始求和;
④我们还需要通过一些方法验证计算结果是否溢出int范围的数据,超过了就直接返回最值,但是这里要根据之前判断的符号位来决定返回的是INT_MAX还是INT_MIN;
⑤一旦出现了数字,如果之后又出现了字符则直接返回之前求的值即可,后面的如果还有数字就不用管了;

代码如下:

class Solution {
public:int myAtoi(string str) {bool sign = true;   //默认为正数// 跳过开头可能存在的空格int i = 0;while(i < str.size() && str[i] == ' ') {i++;}//接着判断首个字符是否为正负号if(str[i] == '-') {sign = false;  // 该字符串为负数,移至下一个字符接着判断i++;          }else if(str[i] == '+')  // 字符串为正数,sign已经默认为true,直接移动到下一位即可i++;   //下面开始对非正负符号位进行判断if(str[i] < '0' || str[i] > '9') // 正常数字第一位必须为0~9之间的数字,否则就是非法数字return 0;  int res = 0;   //这里res用的int型,需要更加仔细考虑边界情况,但如果用long的话可以省去一些麻烦int num = 0; 	//求和int border = INT_MAX / 10;  // 用来验证计算结果是否溢出int范围的数据while(i < str.size()){// 遇到非数字字符,则返回已经计算的res结果if(str[i] < '0' || str[i] > '9') break;// 注意这句话要放在字符转换前,因为需要验证的位数比实际值的位数要少一位, 这里比较巧妙的地方在于// 1. 用低于int型数据长度一位的数据border判断了超过int型数据长度的值 // 2. 将超过最大值和低于最小值的情况都包括了if(res > border || res == border && str[i] > '7')  return sign == true ? INT_MAX : INT_MIN;//开始对数字字符进行转换num = str[i] - '0';res = res * 10 + num;i++;}//最后结果根据符号添加正负号return sign == true ? res : -res;}
};

结果如下:
在这里插入图片描述
🥳🥳这里还提供一种思路:

我们可以先将字符串str中的有效数字及开始的符号位存放在另外一个字符串num中,然后直接将字符串中的字符转换为整型即可;

代码如下:

int myAtoi(string str) {string num;// 如果空字符串,直接返回0if (str.size() == 0){return 0;}int flag = 0; // 记录正负int count = 0;	//利用count来判断是否数字中间有别的符号,有的话就直接break;for (int i = 0; i < str.size(); i++)//遍历字符串{while (str[i] == ' ')//跳过前导空格{i++;}if (count > 1){break;}if (str[i] == '-' || str[i] == '+')//记录符号位{count++;num += str[i];}else if(str[i] >= '0' && str[i] <= '9'){count = 1;num += str[i];}else{count++;}}}

将num里面的字符转换为整型求和这里没写,大家感兴趣可以自己试试

结语

以上就是今天的所有内容啦,通过题目的练习相信大家对于string类的理解和使用又提高了一个层次 ~ 完结撒花~🥳🎉🎉

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

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

相关文章

ASP.NET Web Api 如何使用 Swagger 管理 API

前言 Swagger 是一个开源的框架&#xff0c;支持 OpenAPI 规范&#xff0c;可以根据 API 规范自动生成美观的、易于浏览的 API 文档页面&#xff0c;包括请求参数、响应示例等信息&#xff0c;并且&#xff0c;Swagger UI 提供了一个交互式的界面&#xff0c;可以帮助我们快速…

Java——多线程

一.多线程 1.什么是多线程 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程的实际运作单位 简单理解多线程就是应用软件中相互独立&#xff0c;可以同时运行的功能(也可以理解为人体内相互独立&#xff0c;但可以同时运行的器官⌓‿⌓) 我们…

如何用时尚新姿讲好中国品牌故事?

品牌建设在推动高质量发展中扮演了双重角色&#xff0c;既是高质量发展的重要“承载者”&#xff0c;也是强有力的“助推器”。5月10日-11日&#xff0c;中国时尚品牌URBAN REVIVO&#xff08;以下简称UR&#xff09;以中国品牌日为起点&#xff0c;联合天猫超级品牌日&#xf…

Linux提权--SUDO(CVE-2021-3156)Polkit(CVE-2021-4034)

免责声明:本文仅做技术学习与交流... 目录 SUDO(CVE-2021-3156) 影响版本 -判断&#xff1a; -利用&#xff1a; Polkit(CVE-2021-4034&#xff09; ​ -判断&#xff1a; -利用: 添加用户 SUDO(CVE-2021-3156) another: SUDO权限配置不当. 影响版本 由系统的内核和发…

Redis 5.0 Stream数据结构深入分析

Redis 5.0 Stream数据结构深入分析 目录 Redis 5.0 Stream数据结构深入分析 一、Stream数据结构概述 二、核心概念解析 三、Stream的特性与用途 四、案例研究&#xff1a;实时消息系统 五、性能优化与最佳实践 六、总结与展望 一、Stream数据结构概述 Redis Stream是Red…

FastAPI - Tortoise ORM 数据库基础操作

文章目录 1. 安装 Tortoise ORM2. 定义模型3. 初始化数据库连接4. 数据库操作4.1 创建数据4.2 查询数据4.3 更新数据4.4 删除数据 5. 使用 Pydantic 模型6. 关闭数据库连接7. fields类相关操作1. fields.IntField2. fields.BigIntField3. fields.SmallIntField4. fields.CharFi…

【LAMMPS学习】八、基础知识(6.3)使用 LAMMPS GUI

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语,以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各种模拟。 …

西门子博途WINCC动画之旋转运动

概述 本例将介绍在西门子 TIA Portal HMI 中旋转运动动画的一种实现方法。本例以风机、搅拌器和传送带为例&#xff0c;按下启动按钮开始转动&#xff0c;按下停止按钮停止转动。 第1步&#xff1a; 添加 PLC 设备。​博途TIA/WINCC社区VX群 ​博途TIA/WINCC社区VX群 选择西…

PyQt5中的QGraphicsView()

文章目录 1. 简介2. 一个简单的示例2. 加载一幅图片3. 常用方法示例 1. 简介 QGraphicsView是PyQt5中用于显示图形场景的小部件&#xff0c;它提供了许多常用的方法来控制视图的行为和属性。下面是一些常用的QGraphicsView方法&#xff1a; setScene(scene): 设置要显示的场景…

从零开始写 Docker(十四)---重构:实现容器间 rootfs 隔离

本文为从零开始写 Docker 系列第十四篇&#xff0c;实现容器间的 rootfs 隔离&#xff0c;使得多个容器间互不影响。 完整代码见&#xff1a;https://github.com/lixd/mydocker 欢迎 Star 推荐阅读以下文章对 docker 基本实现有一个大致认识&#xff1a; 核心原理&#xff1a;…

SpringCloud 集成 RocketMQ 及配置解析

文章目录 前言一、SpringCloud 集成 RocketMQ1. pom 依赖2. yml 配置3. 操作实体4. 生产消息4.1. 自动发送消息4.2. 手动发送消息 5. 消费消息 二、配置解析1. spring.cloud.stream.function.definition 前言 定义 Spring Cloud Stream 是一个用来为微服务应用构建消息驱动能力…

spacy微调BERT-NER模型

数据准备 加载数据集 from tqdm.notebook import tqdm import osdataset [] with open(train_file, r) as file:for line in tqdm(file.readlines()):data json.loads(line.strip())dataset.append(data)你可以按照 CLUENER 的格式准备训练数据&#xff0c; 例如&#xff1…

(done) Beam search

参考视频1&#xff1a;https://www.bilibili.com/video/BV1Gs421N7S1/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 &#xff08;beam search 视频&#xff09; 参考博客1&#xff1a;https://jasonhhao.github.io/2020/06/19/…

在word中创建宏来多级列表的编号不显示的bug

出现问题的示意图如下&#xff0c;可以看出标题前面1.1消失了 第一步&#xff1a;选择开发工具 第二步&#xff1a; 第三步&#xff1a;选择当前文件&#xff08;创建宏后&#xff0c;方便查找&#xff09; 第四步&#xff1a; 第五步&#xff1a;打卡VB 第七步&#xf…

ONVIF系列一:ONVIF介绍

感谢博主OceanStar的学习笔记&#xff0c;ONVIF系列二和系列三中安装操作过程及代码实现参考了这位博主的博客。 ONVIF系列&#xff1a; ONVIF系列一&#xff1a;ONVIF介绍 ONVIF系列二&#xff1a;Ubuntu安装gSOAP、生成ONVIF代码框架 ONVIF系列三&#xff1a;ONVIF客户端实现…

机器人开发项目实现过程

比赛项目实现过程 第一步&#xff1a;设置远程桌面连接 登录机器人系统&#xff0c;设置网络&#xff0c;参考远程桌面连接20230525.mp4 外接显示器、鼠标和键盘 登录系统 账户&#xff1a;robuster 密码&#xff1a;123456 建议&#xff0c;手机开热点&#xff0c;机器人…

消费新纪元:探索消费增值的财富之旅

你是否曾对日常消费感到一丝无奈&#xff0c;觉得钱一旦花出去就如同流水般逝去&#xff0c;再也无法追回&#xff1f;现在&#xff0c;让我为你揭示一种革命性的消费观念——消费增值&#xff0c;它不仅能满足你的物质需求&#xff0c;还能让你的资金像滚雪球般持续增长&#…

鸿蒙ArkUI开发:常用布局【弹性布局方向图】

弹性布局方向图 Flex({ direction: FlexDirection.Row }) FlexDirection.Row&#xff08;默认值&#xff09;&#xff1a;主轴为水平方向&#xff0c;子组件从起始端沿着水平方向开始排布FlexDirection.RowReverse&#xff1a;主轴为水平方向&#xff0c;子组件从终点端沿着F…

关于我个人的编码规范(C/C++)

文章目录 前言一、文件结构1. 版权和版本声明&#xff08;不是必须&#xff0c;但是我建议看看&#xff09;2. 头文件结构3. 源文件结构 二、排版&#xff08;以 K&R 风格为主&#xff09;1. 缩进与左花括号的位置2. 空行的插入3. 该分行就分行4. 花括号5. 长语句分段6. 空…

vscode 实现本地服务器部署小结

在查阅 MDN 网站的时候&#xff0c;偶然发现的原来 vscode 也可以实现本地化服务器部署&#xff0c;来模拟服务器的运行。 安装插件 在VSCode的插件市场搜索并安装以下插件&#xff1a; – Live Server&#xff08;用于开启本地服务器&#xff09; – Debugger for Chrome&a…