C++之 string(中)

C++之 string

在这里插入图片描述

string类对象的容量操作

resize

将有效字符的个数该成n个,多出的空间用字符c填充

虽然在string里用的不多,但是在vector里面常见

这里有三种情况:

1)resize小于当前的size

2)resize大于当前的size,小于capacity

3)大于capacity

1)resize小于当前的size

本质上就是删除数据

代码如下:

#include <iostream>
#include <string>
using namespace std;
int main()
{//初始情况string s1("111111");cout << s1.size() << endl;cout << s1.capacity() << endl;return 0;
}

初始情况:

在这里插入图片描述

再来看下面的代码:

#include <iostream>
#include <string>
using namespace std;
int main()
{//初始情况string s1("111111");cout << s1.size() << endl;cout << s1.capacity() << endl;//小于sizes1.resize(3);cout << s1 << endl;return 0;
}

在这里插入图片描述

2)resize大于当前的size,小于capacity

本质是插入

using namespace std;
int main()
{//初始情况string s1("111111");cout << s1.size() << endl;cout << s1.capacity() << endl;//小于sizes1.resize(3);cout << s1 << endl;//resize大于当前的size,小于capacitys1.resize(7,'6');//这里相当于给字符串插入字符,如果不给也不会报错,编译器会自己赋初始值cout << s1 << endl;return 0;
}

在这里插入图片描述

3)大于capacity

using namespace std;
int main()
{//初始情况string s1("111111");cout << s1.size() << endl;cout << s1.capacity() << endl;//小于sizes1.resize(3);cout << s1 << endl;//resize大于当前的size,小于capacitys1.resize(7,'6');cout << s1 << endl;//大于capacitys1.resize(16, '3');return 0;
}

在这里插入图片描述

本质也是插入,大于也不会报错

总结:

resize小于当前的size本质是删除,resize大于当前的size,小于capacity和大于capacity是插入

注意点:

resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不 同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数 增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

string类对象的修改操作

insert

C++是一个极度追求效率的语言,不希望过多的使用头插,头插会使时间复杂度变大,所以就用insert间接替代

代码示例如下:

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1("hello world");s1.insert(5, "xxx");cout << s1 << endl;return 0;
}

打印结果:

在这里插入图片描述

当然最好也是少用,因为影响效率

erase

消除字符串

代码示例如下:

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1("hello world");s1.insert(5, "xxx");cout << s1 << endl;s1.erase(5, 5);//前一个表示要从第几个开始删除,第二个参数表示删除几个cout << s1 << endl;return 0;
}

打印结果:
在这里插入图片描述

注意点:

s1.erase(0, 1);//可以删开头
cout << s1 << endl;
s1.erase(5);//不给删除到第几个,直接后面全删掉
cout << s1 << endl;

打印结果:

在这里插入图片描述

还要注意的是开头的第一个参数不可以越界,会抛异常

s1.erase(55);

replace

只有平替的效率才会高,其余情况不建议使用

示例代码如下:

s1.replace(5, 1, "%%");
cout << s1 << endl;

运行结果如下:

在这里插入图片描述

不推荐的原因在于它会改变位置,影响运行的效率

find

从字符串pos位置开始往后找字符c,返回该字符在字符串中的 位置

代码示例如下:

size_t i = s1.find(" ");
while (i != string::npos)
{s1.replace(i, 1, "%%");i = s1.find(" ");
}
cout << s1 << endl;

打印结果:

在这里插入图片描述

结合之前的范围for,还有更简便的写法:

string s2;
for (auto ch : s1)
{if (ch != ' '){s2 += ch;}else{s2 += "%%";}
}
cout << s2 << endl;

得到的也是同样的结果。

c_str

返回C格式字符串

示例代码如下:

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1("hello world");cout << s1 << endl;cout << s1.c_str() << endl;const char* p1 = "xxxx";int* p2 = nullptr;cout << p1 << endl;//打印不了地址,会自动解引用//cout会自动识别类型,printf可以指定//想要打印成指针,可以强转(void*)cout << (void*)p1 << endl;cout << p2 << endl;return 0;
}

打印结果:
在这里插入图片描述

因为C++也是兼容C语言的,但是它有的不会接收C++的接口,所以要用到c_str,如文件的读:

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1("hello world");cout << s1 << endl;cout << s1.c_str() << endl;const char* p1 = "xxxx";int* p2 = nullptr;cout << p1 << endl;//打印不了地址,会自动解引用//cout会自动识别类型,printf可以指定//想要打印成指针,可以强转(void*)cout << (void*)p1 << endl;cout << p2 << endl;string s2("2024_09_23.cpp");FILE* fout = fopen(s2.c_str(), "r");//不能没有后面的,C语言里这个第一个参数必须//是const*修饰的char ch = fgetc(fout);while (ch!=EOF){cout << ch; ch = fgetc(fout);}return 0;
}

打印结果:

在这里插入图片描述

rfind

从字符串pos位置开始往前找字符c,返回该字符在字符串中的 位置

应用场景如:找文件名后缀

string s3("test.cpp.zip");
size_t pos = s3.rfind('.');
if (pos != string::npos)
{string sub = s3.substr(pos);cout << sub << endl;
}

打印结果:
在这里插入图片描述

注意点在于我这里也用了个新接口

substr

在str中从pos位置开始,截取n个字符,然后将其返回

find_first_of

代码示例如下:

// string::find_first_of
#include <iostream>       // std::cout
#include <string>         // std::string
#include <cstddef>        // std::size_tint main()
{std::string str("Please, replace the vowels in this sentence by asterisks.");std::size_t found = str.find_first_of("aeiou");while (found != std::string::npos){str[found] = '*';found = str.find_first_of("aeiou", found + 1);}std::cout << str << '\n';return 0;
}

在这里插入图片描述

任意一个在里面的值用*替换

not的话就是相当于它的补集关系,其实叫any更好,任意的意思

总的来说:需要重点掌握的接口有以下,以一张思维导图的形式表现:

在这里插入图片描述

上面这些属于不看文档都必须要知道其基本用法的。

一道OJ题:字符串中的第一个唯一字符

给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1

示例 1:

输入: s = "leetcode"
输出: 0

示例 2:

输入: s = "loveleetcode"
输出: 2

示例 3:

输入: s = "aabb"
输出: -1

提示:

  • 1 <= s.length <= 105
  • s 只包含小写字母

代码:

class Solution {
public:int firstUniqChar(string s) {int count[26]={0};//统计次数for(auto ch:s){//间接映射count[ch-'a']++;}//再遍历索引(下标)for(size_t i=0;i<s.size();++i){if(count[s[i]-'a']==1){return i;}}return -1;}
};

一道OJ题:字符串最后一个单词的长度

描述

计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)

输入描述:

输入一行,代表要计算的字符串,非空,长度小于5000。

输出描述:

输出一个整数,表示输入字符串最后一个单词的长度。

示例1

输入:
hello nowcoder
输出:
8
说明:
最后一个单词为nowcoder,长度为8

代码:

#include <iostream>
using namespace std;
#include<string>
int main() {string str;
// 不要使用cin>>line,因为会它遇到空格就结束了
// while(cin>>line)getline(cin,str);size_t pos=str.rfind(' ');cout<<str.size()-(pos+1)<<endl;//左闭右开,减出来才是个数return 0;}

这里我们需要来介绍一个接口:getline

获取一行字符串

遇到换行的时候会自动结束

像我们之前遇到的scanf,cin都是连续地从流中提取数据,因为它会把数据放到缓冲区里,默认空格,换行是分割,因为一个一个字符地区提取效率会很低

来看下面代码示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1, s2;cin >> s1 >> s2;cout << s1 << endl;cout << s2 << endl;return 0;
}

打印结果:
在这里插入图片描述

另外一种情况:

string str;
getline(cin, str, '#');
//指定字符,遇到这个字符就会停止流输入

在这里插入图片描述

一道OJ题:验证回文串

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false

示例 1:

输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。

示例 2:

输入:s = "race a car"
输出:false
解释:"raceacar" 不是回文串。

示例 3:

输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。
由于空字符串正着反着读都一样,所以是回文串。

提示:

  • 1 <= s.length <= 2 * 105
  • s 仅由可打印的 ASCII 字符组成

代码如下:

class Solution {
public:bool isLetterOrNumber(char ch){return (ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<'Z');}bool isPalindrome(string s) {for(auto&ch:s){if(ch>='a'&&ch<='z')ch-=32;}int begin=0,end=s.size()-1;while(begin<end){while(begin<end&&!isLetterOrNumber(s[begin]))++begin;while(begin<end&&!isLetterOrNumber(s[end]))--end;if(s[begin]!=s[end])    {return false;}else{++begin;--end;}}return true;}
};

string类的模拟实现

在面试中,面试官总喜欢让 学生自己来模拟实现string类,最主要是实现string类的构造、拷贝构造、赋值运算符重载以及析 构函数。

下面是关于构造,析构,迭代器,尾插的模拟实现

string.h

#pragma once
#include <iostream>
#include <assert.h>
#include <string>
using namespace std;
namespace Tzuyu
{class string{public:string(const char* str = " ");~string();void reserve(size_t n);void push_back(char ch);void append(const char* str);string& operator+=(char ch);//不建议过多使用,因为是全局变量string& operator+=(const char* str);char& operator[](size_t i){assert(i < _size);return _str[i];}const char& operator[](size_t i) const{assert(i < _size);return _str[i];}using iterator = char*;using const_iterator = const char*;iterator begin()//范围for底层是迭代器,必须要规范,如这里的begin,如果是Begin就不行,范围for会报错{return _str;}iterator end(){return _str + _size;}const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}size_t size() const{return _size;}const char* c_str() const{return _str;}private :char* _str;size_t _size;size_t _capacity;};
}

string.cpp

#include "string.h"
namespace Tzuyu
{string::string(const char* str):_size(strlen(str)){_capacity = _size;_str = new char[_size + 1];strcpy(_str, str);}string::~string(){delete[]_str;_str = nullptr;_size = 0;_capacity = 0;}void string::push_back(char ch){if (_size == _capacity){reserve(_capacity == 0 ? 4 : _capacity * 2);}_str[_size] = ch;_size++;}void string::append(const char* str){size_t len = strlen(str);if (_size + len > _capacity){size_t newCapacity = 2 * _capacity;//扩2倍不够,则需多少扩多少if (newCapacity < _size + len)newCapacity = _size + len;reserve(newCapacity);}strcpy(_str + _size, str);_size += len;}void string::reserve(size_t n){if (n > _capacity){char* tmp = new char[n + 1];//预留一个空间,因为reserve是内外都好用strcpy(tmp, _str);delete[]_str;_str = tmp;_capacity = n;}}string&string:: operator+=(char ch){push_back(ch);return*this;}string& string:: operator+=(const char* str){append(str);return*this;}
}

test.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include "string.h"int main()
{Tzuyu::string s2;cout << s2.c_str() << endl;Tzuyu::string s1("hello world");cout << s1.c_str() << endl;s1[0] = 'x';cout << s1.c_str() << endl;Tzuyu::string::iterator it1 = s1.begin();while (it1 != s1.end()){(*it1)--;++it1;}cout << endl;it1 = s1.begin();while (it1 != s1.end()){cout << *it1 << " ";++it1;}cout << endl;for (auto& ch : s1){ch++;}for (auto ch : s1) {cout << ch << " ";}cout << endl;const string s3("xxxxxxxx");for(auto& ch : s3){//ch++;//不可以这样进行操作,因为auto自动推导的时候发现的是const修饰的,不能修改cout << s3 << " ";}cout << endl;return 0;
}

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

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

相关文章

计算机视觉的应用34-基于CV领域的人脸关键点特征智能提取的技术方法

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用34-基于CV领域的人脸关键点特征智能提取的技术方法。本文主要探讨计算机视觉领域中人脸关键点特征智能提取的技术方法。详细介绍了基于卷积神经网络模型进行人脸关键点提取的过程&#xff0c;包括使…

一、Kafka入门

一、消息中间件 1、为什么使用消息中间件&#xff1f; 异步解耦削峰填谷 2、异步 3、解耦 异步处理使整个数据操作流程解耦&#xff0c;如果短信服务或者积分服务异常&#xff0c;不影响前面重要的功能。 面试问题点&#xff1a; 所以尽量将不重要的服务放到下游&#xf…

闲盒支持的组网方式和注意事项

1. 直连光猫拨号​ 通过光猫拨号&#xff0c;设备直连光猫的设备&#xff0c;需要对光猫开启UPNP并关闭DMZ 如果只接一个盒子&#xff0c;建议直接针对盒子IP开dmz。 2. 直连路由器​ 通过路由器拨号&#xff0c;设备直连路由器的设备&#xff0c;需要对路由器开启UPNP并关闭…

Spring Security学习

系列文章目录 第一章 基础知识、数据类型学习 第二章 万年历项目 第三章 代码逻辑训练习题 第四章 方法、数组学习 第五章 图书管理系统项目 第六章 面向对象编程&#xff1a;封装、继承、多态学习 第七章 封装继承多态习题 第八章 常用类、包装类、异常处理机制学习 第九章 集…

如何防止U盘资料被复制?这六个策略你值得牢记!

随着U盘广泛应用于企业和个人数据存储&#xff0c;如何防止U盘资料被非法复制和泄露成为企业信息安全的重要问题。 U盘作为便携的数据存储设备&#xff0c;虽然方便&#xff0c;但也带来了数据泄露的风险。 为了有效防止U盘资料被复制&#xff0c;以下六个策略能够帮助企业和个…

gradio交互式界面部署

gradio交互式界面部署 示例&#xff1a;http://xxxxx:1111/api/v1/my_model 为模型服务api&#xff0c;传入参数为&#xff1a; {"company": company,"name": name,"t_date": t_date,"amount": amount,"img1_path": img1_…

LeetCode Hot100 C++ 哈希 128.最长连续序列

128.最长连续序列 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff0…

怎么测试射频芯片质量的好坏?

无论是手机通信&#xff0c;还是卫星导航&#xff0c;射频芯片都是其核心组件之一。本文将探讨如何准确判断射频芯片的质量&#xff0c;以确保技术设备的稳定运行。 1. 外观检查 检查射频芯片是否有破损、引脚断裂、缺陷等。 2. 电气参数测试 对射频芯片的输入输出阻抗、功耗、…

RabbitMQ:交换机详解(Fanout交换机、Direct交换机、Topic交换机)

♥️作者&#xff1a;小宋1021 &#x1f935;‍♂️个人主页&#xff1a;小宋1021主页 ♥️坚持分析平时学习到的项目以及学习到的软件开发知识&#xff0c;和大家一起努力呀&#xff01;&#xff01;&#xff01; &#x1f388;&#x1f388;加油&#xff01; 加油&#xff01…

伊犁云计算22-1 rhel8 dhcp 配置

1 局域网搭建 2 yum 配置 这个参考前面 不说 3 dnf 安装dhcp 好我们废话不说开始安装。理论看书去 进入 dhcp.conf 配置 重启dhcpd 不能报错&#xff01;&#xff01;&#xff01;&#xff01; 我们在客户机上做测试 全局的dhcp关闭 很明显我们的客户机获取到192.16…

libreoffice word转pdf

一、准备一个word文件 运行&#xff1a; cd /root libreoffice --headless --convert-to pdf --outdir /root/output doc1.docx 发现中文乱码&#xff1a; 此时我们需要给linux 上添加中文字体&#xff1a; centos7 添加中文字体 再次运行正常&#xff1a; libreoffice --h…

如何使用Postman搞定带有token认证的接口实战!

现在许多项目都使用jwt来实现用户登录和数据权限&#xff0c;校验过用户的用户名和密码后&#xff0c;会向用户响应一段经过加密的token&#xff0c;在这段token中可能储存了数据权限等&#xff0c;在后期的访问中&#xff0c;需要携带这段token&#xff0c;后台解析这段token才…

基于SpringBoot社区疫情信息管理系统的设计和实现

文未可获取一份本项目的java源码和数据库参考。 选题的意义 保护好人民群众的基本安全&#xff0c;贯彻党的领导下中国一盘棋的基本准则。将病毒隔绝在外&#xff0c;信息系统的存在显得至关重要&#xff0c;应对新型冠状病毒肺炎疫情治理的实践背景。实时关注更新疫情动态&a…

支持K歌音箱方案应用的高性能 32 位蓝牙音频应用处理器-BP1048B2

DSP是一类嵌入式通用可编程微处理器&#xff0c;主要用于实现对信号的采集、识别、变换、增强、控制等算法处理&#xff0c;是各类嵌入式系统的“大脑”应用十分广泛。BP1048B2是一款高性能DSP音频数字信号处理器芯片&#xff0c;能实现多种音频功能如混响、均衡、滤波、反馈抑…

Vue 自定义指令实现权限控制

一. 引言 Vue.js 提供了一种简单、灵活的方式来创建交互式的用户界面。在 Vue.js 中&#xff0c;指令是一种特殊的属性&#xff0c;可以附加到 HTML 元素上以执行一些操作。我们可以使用自定义指令来实现各种功能&#xff0c;比如&#xff1a;权限控制、自动聚焦、拖动指令等等…

通过docker启动ElasticSearch后为ElasticSearch设置用户和密码

文章目录 0. 前言1. 没有设置用户名和密码的情况2. 为ElasticSearch设置用户名和密码2.1 进入 ElasticSearch 容器内部2.2 修改 ElasticSearch 的配置文件2.3 设置用户名和密码 3. 在 kibana 容器中指定访问 ElasticSearch 的用户名和密码4. 设置用户名和密码后的情况4.1 访问 …

[51单片机] 简单介绍 (一)

文章目录 1.单片机介绍2.单片机内部三大资源3.单片机最小系统4.STC89C52RC单片机 1.单片机介绍 兼容Intel的MCS-51体系架构的一系列单片机。 STC89C52&#xff1a;8K FLASH、512字节RAM、32个IO口、3个定时器、1个UART、8个中断源。 单片机简称MCU单片机内部集成了CPU、RAM、…

Maxim(美信)—MAX20079AATP/VY PMIC芯片详解

写在前面 本系列文章主要讲解Maxim&#xff08;美信&#xff09;—MAX20079AATP/VY PMIC芯片的相关知识&#xff0c;希望能帮助更多的同学认识和了解MAX20079AATP/VY芯片。 若有相关问题&#xff0c;欢迎评论沟通&#xff0c;共同进步。(*^▽^*) PMIC是Power Management Int…

CC面试准备

半导体基础 半导体是介于导体和绝缘体之间的一种介质&#xff0c;在不同条件下表现出不同的导电性或者不导电特性&#xff0c; 电子半导体器件材料大部分为硅&#xff0c;锗等元素 本征半导体&#xff1a;完全不含杂质的纯净半导体&#xff0c;因为不含杂质&#xff0c;其中…

QT widgets 窗口缩放,自适应窗口大小进行布局

1. 窗口布局 2. 尺寸策略&#xff1a;扩展 Fixed (固定): 行为&#xff1a;控件的大小是固定的&#xff0c;不会随着窗口大小的变化而改变。它的大小由控件的 sizeHint() 返回的值决定。 适用场景&#xff1a;当你希望控件的大小保持不变&#xff0c;不随布局调整时使用&#x…