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.rhkb.cn/news/431672.html

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

相关文章

重生之我在代码随想录刷算法第十三天 | 110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和、222.完全二叉树的节点个数

参考文献链接&#xff1a;代码随想录 本人代码是Java版本的&#xff0c;如有别的版本需要请上代码随想录网站查看。 110.平衡二叉树 力扣题目链接 解题思路 这道题目刚看到以为和二叉树的最大深度差不多&#xff0c;上来写了一堆迭代求深度的代码结果发现不对劲。 看了题…

通过WinCC在ARMxy边缘计算网关上实现智能运维

随着信息技术与工业生产的深度融合&#xff0c;智能化运维成为提升企业竞争力的关键因素之一。ARMxy系列的ARM嵌入式计算机BL340系列凭借其高性能、高灵活性和广泛的适用性&#xff0c;为实现工业现场的智能运维提供了坚实的硬件基础。 1. 概述 ARMxy BL340系列是专为工业应用…

wpf在图上画矩形,矩形可拖动、大小可调节,使用装饰器Adorner调整矩形大小,限制拖动和调节范围

效果 功能 使用wpf实现 在图片上画一个矩形框该矩形框可以调节大小该矩形框可以拖动调整位置 注&#xff1a;这里的鼠标事件是&#xff0c;双击在图上画一个固定大小的矩形框&#xff0c;右键按住拖动矩形框。有需要的可以自行调整对应的鼠标事件 参考资料&#xff1a;https…

vant van-pull-refresh + van-list实现list列表支持搜索和下拉刷新

1 介绍 在使用 van-pull-refresh van-list实现list列表下拉刷新时遇到几个问题在这里进行一个总结。 2 出现的问题 问题一&#xff1a;当van-pull-refresh van-list组合使用时&#xff0c;下拉刷新会调用两个加载图标。 解答&#xff1a;去除van-pull-refresh加载图标&…

刷题小记3----每日一题精进Java技能(详细思路解析✅)

文章目录 一、两种排序方法二、最小公倍数三、另类加法四、倒置字符串五、统计回文 一、两种排序方法 题目链接&#xff1a;两种排序方法 题目描述&#xff1a; 考拉有n个字符串字符串&#xff0c;任意两个字符串长度都是不同的。考拉最近学习到有两种字符串的排序方法&#x…

Web端云剪辑解决方案,提供前端产品源码

美摄科技作为业界领先的视频技术服务商&#xff0c;匠心打造Web端云剪辑解决方案&#xff0c;以前沿技术赋能企业用户&#xff0c;开启视频创作与编辑的新纪元。 【云端赋能&#xff0c;重塑剪辑体验】 美摄科技的Web端云剪辑解决方案&#xff0c;颠覆了传统视频编辑的局限&a…

zabbix“专家坐诊”第257期问答

问题一 Q&#xff1a;zabbix5.0监控项里的键值&#xff0c;怎么设置变量值&#xff1f;{#ABC} {$ABC} 都识别不到变量。 A&#xff1a;可以参考一下这个。 问题二 Q&#xff1a;我想问一下用odbc创建监控项&#xff0c;生成了json格式&#xff0c;如何创建一个触发器去判断里面…

人工智能武器化与国家网络威慑机制选择

文章目录 前言一、人工智能武器化与国家网络威慑机制选择1、人工智能时代国家推动网络威慑的逻辑二、迈向攻防平衡期的网络威慑机制选择三、攻防平衡状态下的网络威慑机制选择前言 威慑理论是国家应对战争威胁的重要思想,同时也是一种严格的信号传递机制。自21世纪初期“网络…

方法部分 学习

方法是程序中最小的执行单元 方法的定义调用 public static void 方法名&#xff08;&#xff09;{ 方法体 } 写在main方法外面&#xff0c;在main函数里面直接调用带参数&#xff1a;public static void 方法名&#xff08;int num1 &#xff0c; int num2&am…

成都睿明智科技有限公司电商服务引领品牌跃升

在当今这个数字化浪潮汹涌的时代&#xff0c;抖音电商以其独特的魅力迅速崛起&#xff0c;成为众多品牌商家竞相追逐的新战场。在这片充满机遇与挑战的领域中&#xff0c;成都睿明智科技有限公司以其专业的抖音电商服务&#xff0c;成为了众多商家信赖的伙伴。今天&#xff0c;…

在虚幻引擎中创建毛发/头发

在虚幻引擎中创建毛发/头发 , 首先开启两个插件 Groom 和 Alembic Groom Importer 打开蒙皮缓存 导出人物模型 将人物导入Blender , 选择需要种植头发的点 指定并选择 点击毛发 这里变成爆炸头了 , 把数量和长度调一下 切换到梳子模式 调整发型 导出为abc , 文件路径不…

针对 Linux SSH 服务器的新攻击:Supershell 恶意软件危害易受攻击的系统

ASEC 研究人员发现了针对保护不善的 Linux SSH 服务器的新攻击。 在其中&#xff0c;黑客使用了用Go编写的 Supershell恶意软件。 该后门使攻击者能够远程控制受感染的系统。 初次感染后&#xff0c;黑客启动扫描仪来寻找其他易受攻击的目标。 据信这些攻击是使用从已受感…

kubernetes K8S 挂载分布式存储 ceph

目录 一、Ceph简介 二、Ceph核心组件介绍 三、安装Ceph集群 1初始化实验环境 1.1、配置静态IP&#xff1a; 1.2、配置主机名&#xff1a; 1.3、配置hosts文件&#xff1a; 1.4、配置互信 1.5、关闭防火墙 1.6、关闭selinux 1.7、配置Ceph安装源 1.8、配置时间同步 …

【自学笔记】支持向量机(4)——支持向量回归SVR

引入 SVM解决了分类问题&#xff0c;而用类似方法解决回归问题的模型称为支持向量回归。目标是得到一个模型&#xff0c;使输出的 f ( x ⃗ ) f(\vec{x}) f(x )与 y y y尽可能接近。 传统的回归模型直接计算 f ( x ⃗ ) f(\vec{x}) f(x )与 y y y的差距作为损失&#xff0c;当两…

Linux驱动开发(速记版)--驱动基础

第一章 初识内核源码 Linux系统源码提供了操作系统的核心功能&#xff0c;如进程管理、内存管理、文件系统等。 BusyBox这类的文件系统构建工具&#xff0c;则提供了在这些核心功能之上运行的一系列实用工具和命令&#xff0c;使得用户能够执行常见的文件操作、文本处理、网络配…

爬虫逆向学习(八):Canvas画图滑块验证码解决思路与绕过骚操作

此分享只用于学习用途&#xff0c;不作商业用途&#xff0c;若有冒犯&#xff0c;请联系处理 逆向站点 aHR0cHM6Ly93d3cuYm9odWF5aWNhaS5jbi8/VTU4Iy9jaGVtaWNhbC9sb2dpbj9yZWRpcmVjdD0lMkZjaGVtaWNhbA 滑块验证码样式 滑块验证码研究 一般的滑块验证码都是会直接提供滑块和…

Diffusion Model Stable Diffusion(笔记)

参考资料&#xff1a; 文章目录 DDPM架构模型如何拥有产生逼真图片的能力Denoise模型功能Denoise模型如何训练考虑进文字 文生图流程(Stable Diffusion) DDPM架构 模型如何拥有产生逼真图片的能力 Denoise模型功能 通过Denoise将一个噪音图一步步生成为目标图像 Denoise实际…

【开源免费】基于SpringBoot+Vue.JS墙绘产品展示交易平台(JAVA毕业设计)

本文项目编号 T 049 &#xff0c;文末自助获取源码 \color{red}{T049&#xff0c;文末自助获取源码} T049&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

echarts根据容器宽度动态截取展示横坐标名称

效果如下&#xff1a; 初始状态&#xff1a; 缩放页面后&#xff1a; 代码地址&#xff1a;代码地址-面包多

Oracle 19c 使用EMCC 监控当前所有数据库

一.EMCC简介 EMCC&#xff0c;全称Oracle Enterprise Manager Cloud Control&#xff0c;是Oracle提供的一套集中化监控工具&#xff0c;可以对数据库、操作系统、中间件等进行监控&#xff0c;通过OMS&#xff08;Oracle Management Service&#xff09;收集监控数据并将监控信…