标准库中的string类(中)+仅仅反转字母+字符串中的第一个唯一字符+字符串相加——“C++”“Leetcode每日一题”

各位CSDN的uu们好呀,今天,继续小雅兰西嘎嘎的学习,标准库中的string类,下面,让我们一起进入西嘎嘎string的世界吧!!!


string类的常用接口说明

Leetcode每日一题


string类的常用接口说明

标准库中的string类(上)——“C++”-CSDN博客

string类对象的容量操作

max_size 

max_size:能开的最大的大小空间!

int main()
{string s1;string s2("hello world");cout << s1.max_size() << endl;cout << s2.max_size() << endl;return 0;
}

不同的编译器下 这个值都是不一样的!所以没有什么参考意义!

它说能开这么大的空间,但是实际上,真的能开这么大的空间吗?答案是不一定的!


reserve 

reserve  保留

reverse 反转 逆置

抛异常了! 

try
{string s1;string s2("hello world");// 实践中没有参考和使用的价值cout << s1.max_size() << endl;cout << s2.max_size() << endl;s1.reserve(s1.max_size());
}
catch (const exception& e)
{cout << e.what() << endl;
}

虽然这个东西没有什么价值,可是也不能把它删掉,现在的编译器只能向前兼容,因为怕之前有人用这个功能写了一个什么东西,本来用的好好的,结果编译器一更新,反而报错了!


 capacity 

 

try
{string s1;string s2("hello world");cout << s1.capacity() << endl;cout << s2.capacity() << endl;
}
catch (const exception& e)
{cout << e.what() << endl;
}

 容量都是15!

但是实际上,空间不是开了15,而是开了16!

为什么开了16呢?因为在这个地方,容量不是指的开的多大的空间,它是指的我到底能存多少有效字符!为什么这两个东西不同呢?空间是多大和到底能存储多少个有效字符为什么不是等价的呢?因为有‘\0’,在结尾处标识的这个‘\0’不算有效字符!

现在capacity是15,代表我能存储15个有效字符,但是我空间必须得多开一个,用来放'\0'!

现在,这个capacity的值就变了!实际上开的空间大小是48!!!

下面,我们可以来检测一下string的扩容机制:

int main()
{
    try
    {
        string s1;
        string s2("hello worldxxxxxxxxxxxxx");
      

        size_t old = s1.capacity();
        cout << old << endl;

        //检测string的扩容机制
        for (size_t i = 0; i < 500; i++)
        {
            s1.push_back('x');
            if (old != s1.capacity())
            {
                cout << s1.capacity() << endl;
                old = s1.capacity();
            }
        }
    }
    catch (const exception& e)
    {
        cout << e.what() << endl;
    }

    return 0;
}

 

 

 

不同的编译器下,扩容机制也是不一样的!

但是扩容的代价是非常大的,所以:确定需要多少空间,提前开好空间即可!

s1.reserve(500);

但是不一定是开500,也有可能比500大!!!

但是开了511! 

 

研究这个其实也是没有意义的!因为不同的编译器下所做的不同,VS下就进行了对齐!!!

所以有的时候,尤其是一些和空间、容量相关的代码,在不同的平台下,所运行的结果不同,这是可以理解的!!! 

函数名称 功能说明
size(重点)返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小
empty(重点)检测字符串释放为空串,是返回true,否则返回false
clear(重点)清空有效字符
reserve(重点)为字符串预留空间
resize(重点)将有效字符的个数该成n个,多出的空间用字符c填充

注意:

  • size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一 致,一般情况下基本都是用size()。
  • clear()只是将string中有效字符清空,不改变底层空间大小。
  • resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。  
  • reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

resize 

 

 reserve是用来扩容的,那么它会不会缩容呢?

int main()
{string s1;cout << s1.capacity() << endl;s1.reserve(10);cout << s1.capacity() << endl;string s2("hello worldxxxxxxxxxxxxx");cout << s2.capacity() << endl;s2.reserve(10);cout << s2.capacity() << endl;return 0;
}

不管是有数据还是没数据,reserve都是不会缩容的!可以理解为reserve仅仅是用来扩容的!

缩容的代价比较大!!!

但是:在不同的编译器下,所产生的结果仍然是不一样的!在Linux下,就会缩容;在VS下,就不会缩容!

在Linux下,确实会缩容,但是这个缩容又比较“怪异”,如果是有数据的情况下,缩容后的容量比现有的size还要小,不会删除数据,最小缩到size!!!

综上所述:reserve只影响空间(容量),不影响数据!

可是:resize就不一样了!它既影响容量,也影响数据!

 

int main()
{string s1("hello world");cout << s1.size() << endl;cout << s1.capacity() << endl;cout << s1 << endl;s1.resize(100);cout << s1.size() << endl;cout << s1.capacity() << endl;cout << s1 << endl;return 0;
}

 

 

int main()
{string s1("hello world");cout << s1.size() << endl;cout << s1.capacity() << endl;cout << s1 << endl;//> capacity//s1.resize(100);s1.resize(100, 'x');cout << s1.size() << endl;cout << s1.capacity() << endl;cout << s1 << endl;// size < n < capacitystring s2("hello world");cout << s2.size() << endl;cout << s2.capacity() << endl;cout << s2 << endl;s2.resize(12);cout << s2.size() << endl;cout << s2.capacity() << endl;cout << s2 << endl;return 0;
}

当size < n < capacity时,在VS下,也不会缩容!

int main()
{string s1("hello world");cout << s1.size() << endl;cout << s1.capacity() << endl;cout << s1 << endl;//> capacity		扩容+尾插//s1.resize(100);s1.resize(100, 'x');cout << s1.size() << endl;cout << s1.capacity() << endl;cout << s1 << endl;// size < n < capacity		尾插string s2("hello world");cout << s2.size() << endl;cout << s2.capacity() << endl;cout << s2 << endl;s2.resize(12);cout << s2.size() << endl;cout << s2.capacity() << endl;cout << s2 << endl;// n < size		删除数据,保留前n个string s3("hello world");cout << s3.size() << endl;cout << s3.capacity() << endl;cout << s3 << endl;s3.resize(10);cout << s3.size() << endl;cout << s3.capacity() << endl;cout << s3 << endl;return 0;
}

 

那在Linux下,又是不是这样呢?

我们会发现,在Linux下,resize也是不会缩容的!!!

 


at 

 

 int main()
{
    try
    {
        string s1("hello world");
        cout << s1[11] << endl;
        cout << s1[20] << endl;
    }
    catch (const exception& e)
    {
        cout << e.what() << endl;
    }
    return 0;
}

在C语言中,数组越界访问是不会报错的,可是在西嘎嘎中,就报错了! 

at和[]的功能是一样的!!!

int main()
{
    try
    {
        string s1("hello world");
        cout << s1[11] << endl;
        //cout << s1[20] << endl;
        cout << s1.at(20) << endl;
    }
    catch (const exception& e)
    {
        cout << e.what() << endl;
    }
    return 0;

一个是偏暴力一点的检查,一个是偏温柔一点的检查! 

一般是用[]比较多,也就是偏暴力一点!

剩下的back和front是C++11的新特性! 


string类对象的修改操作

  • 增 +=(push_back/append)/insert
  • 删 erase
  • 查 []
  • 改 []/at/迭代器
函数名称 功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
opeator+=在字符串后追加字符串str
C str返回C格式字符串
find+npos从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回

注意:

  • 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
  • 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

 append 

 

int main()
{string s1("hello");s1.push_back(' ');s1.append("world");cout << s1 << endl;return 0;
}

int main()
{string s1("hello");s1.push_back(' ');s1.append("world");cout << s1 << endl;string s2 = "xxxx";const string& s3 = "xxxxxxxx";s2.append(++s1.begin(), --s1.end());cout << s2 << endl;return 0;
}

 

 但是,不管是push_back还是append,都不是西嘎嘎最喜欢用的,西嘎嘎最喜欢用的是这个:


 operator+= 

int main()
{
    string s1("hello");
    s1.push_back(' ');
    s1.append("world");
    cout << s1 << endl;

    string s2 = "xxxx";
    const string& s3 = "xxxxxxxx";
    
    s2.append(++s1.begin(), --s1.end());
    cout << s2 << endl;

    s1 += '!';
    s1 += "xxxxx";
    s1 += s2;
    cout << s1 << endl;
    return 0;
}

 


Leetcode每日一题 

 仅仅反转字母

 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

 

 

class Solution {public:bool isLetter(char ch){if(ch >= 'a' && ch <= 'z')return true;if(ch >= 'A' && ch <= 'Z')return true;return false;}string reverseOnlyLetters(string S) {if(S.empty())return S;size_t begin = 0, end = S.size()-1;while(begin < end){while(begin < end && !isLetter(S[begin]))++begin;while(begin < end && !isLetter(S[end]))--end;swap(S[begin], S[end]);++begin;--end;}return S;}};

 

 字符串中的第一个唯一字符

 

class Solution {
public:int firstUniqChar(string s) {int count[26]={0};for(auto ch:s){count[ch-'a']++;//'a'的ASCII码值是97//计数}//找第一个只出现一次的//再次遍历,拿到每个字符for(size_t i=0;i<s.size();i++){if(count[s[i]-'a']==1){return i;}}return -1;}
};

 

另一种写法:

class Solution {public:int firstUniqChar(string s) {// 统计每个字符出现的次数int count[256] = {0};int size = s.size();for(int i = 0; i < size; ++i)count[s[i]] += 1;// 按照字符次序从前往后找只出现一次的字符for(int i = 0; i < size; ++i)if(1 == count[s[i]])return i;return -1;}
};

字符串相加

 “大数运算”

class Solution {
public:string addStrings(string num1, string num2) {int end1=num1.size()-1;int end2=num2.size()-1;//进位int next=0;string retStr;while(end1>=0||end2>=0){int value1=0;int value2=0;if(end1>=0){value1=num1[end1--]-'0';}if(end2>=0){value2=num2[end2--]-'0';}int ret=value1+value2+next;next=ret/10;ret=ret%10;retStr+=('0'+ret);}if(next==1){retStr+='1';}reverse(retStr.begin(),retStr.end());return retStr;}
};


好啦,小雅兰今天的string类的使用以及Leetcode每日一题的内容就到这里啦,下篇博客继续string类的使用!!!加油!!!奥利给!!!

 

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

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

相关文章

pip 常用指令 pip install 命令用法介绍

pip install 是一个 Python 包管理器命令&#xff0c;用于安装 Python 包。pip 是 Python 的一个重要工具&#xff0c;可以用来安装、升级和卸载 Python 包。 pip install 命令的一些常见参数有 -r&#xff1a;从一个需求文件中安装所有的包。-U 或 --upgrade&#xff1a;升级…

鸿蒙开发基本概念

1、开发准备 1.1、UI框架 HarmonyOS提供了一套UI开发框架&#xff0c;即方舟开发框架&#xff08;ArkUI框架&#xff09;。方舟开发框架可为开发者提供应用UI开发所必需的能力&#xff0c;比如多种组件、布局计算、动画能力、UI交互、绘制等。 方舟开发框架针对不同目的和技术…

基于MLP完成CIFAR-10数据集和UCI wine数据集的分类

基于MLP完成CIFAR-10数据集和UCI wine数据集的分类&#xff0c;使用到了sklearn和tensorflow&#xff0c;并对图片分类进行了数据可视化展示 数据集介绍 UCI wine数据集&#xff1a; http://archive.ics.uci.edu/dataset/109/wine 这些数据是对意大利同一地区种植的葡萄酒进…

[SWPUCTF 2021 新生赛]jicao

首先打开环境 代码审计&#xff0c;他这儿需要进行GET传参和POST传参&#xff0c;需要进行POST请求 变量idwllmNB&#xff0c;进行GET请求变量json里需要含参数x以及jsonwllm 构造 得到flag

在线更换Proxmox VE超融合集群Ceph OSD磁盘

因为资源紧张的原因&#xff0c;担心一旦关机&#xff0c;虚拟机因为没有空闲的资源而被冻结&#xff0c;以致于不能漂移&#xff0c;导致部分服务停止&#xff0c;只好让机房帮忙热插拔。 幸运的是&#xff0c;插上去能够被系统所识别&#xff08;/dev/sdf就是新插入的硬盘&am…

华为数通方向HCIP-DataCom H12-831题库(多选题:181-200)

第181题 如图所示,R1、R2、R3、R4都部署为SPF区域0,链路的cost值如图中标识。R1、R2R3、R4的Loopback0通告入OSPF。R1、R2、R3与R4使用Loopback0作为连接接口,建立BGP对等体关系,其中R4为RR设备,R1、R2、R3是R4的客户端。当R4的直连地址172.20,1,4/32通告入BGP后,以下关R…

mysql部署 --(docker)

先查找MySQL 镜像 Docker search mysql &#xff1b; 拉取mysql镜像&#xff0c;默认拉取最新的&#xff1b; 创建mysql容器&#xff0c;-p 代表端口映射&#xff0c;格式为 宿主机端口&#xff1a;容器运行端口 -e 代表添加环境变量&#xff0c;MYSQL_ROOT_PASSWORD是root用户…

2024云渲染平台推荐!免费云渲染平台(注册账号)推荐

近期&#xff0c;由于信息科技和云计算的迅猛发展&#xff0c;云渲染服务也逐步蓬勃发展并已达到成熟阶段&#xff0c;它因其高效办公、成本效益优越以及操作简便易行&#xff0c;赢得了广大设计师和 CG 艺术家的热烈欢迎&#xff0c;在过去的岁月里&#xff0c;创造一张高清晰…

OpenCV技术应用(8)— 如何将视频分解

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。本节课就手把手教大家如何将一幅图像转化成热力图&#xff0c;希望大家学习之后能够有所收获~&#xff01;&#x1f308; 目录 &#x1f680;1.技术介绍 &#x1f680;2.实现代码 &#x1f680;1.技术介绍 视频是…

charles和谷歌浏览器在Mac上进行软件安装,桌面上会显示一个虚拟磁盘,关掉页面推出磁盘内容都消失掉了 需要再次安装问题解决

其他软件也会有这种情况&#xff0c;这里我们以charles为例。绿色背景的内容是重点步骤。 1.如图&#xff0c;我下载了一个charles一个版本的dmg文件。 2.打开后&#xff0c;选择Agree 3.桌面会出现一个磁盘和如下页面 4.错误操作------可以不看 直接看第5步正确操作 常规情…

Socket.D 基于消息的响应式应用层网络协议

首先根据 Socket.D 官网的副标题&#xff0c;Socket.D 的自我定义是&#xff1a; 基于事件和语义消息流的网络应用协议。官网定义的特点是&#xff1a; 基于事件&#xff0c;每个消息都可事件路由所谓语义&#xff0c;通过元信息进行语义描述流关联性&#xff0c;有相关的消息…

Android Studio设置android:background 属性背景颜色

除了默认的颜色之外都要自己添加。 添加颜色的操作步骤&#xff1a; 打开res文件夹&#xff0c;找values&#xff0c;里面有个colors.xml的文件。然后在里面定义一些颜色。 完成

21、Web攻防——JavaWeb项目JWT身份攻击组件安全访问控制

文章目录 一、JavaWeb二、JWT攻击 一、JavaWeb webgoat 1.java web的配置文件&#xff0c;配置文件一般在META-INF目录下&#xff0c;文件名常为pom.xml或web.xml 2.如何通过请求&#xff0c;查看运行的java代码。 地址信息PathTraversal/profile-upload 直接找到以该字符P…

网络安全知识图谱 图数据库介绍及语法

本体构建: 资产&#xff1a; 系统&#xff0c;软件 威胁&#xff1a; 攻击&#xff1a; 建模&#xff1a; 3个本体 5个实体类型 CWE漏洞库 http://cwe.mitre.org/data/downloads.html CPECP攻击模式分类库 http://capec.mitre.org/data/downloads.html CPE通用组件库 http:…

Modbus RTU协议与S7 200 PLC通讯

一、Modbus RTU功能码 二、功能码使用与解析实例 01功能码 –读线圈状态 主机发送&#xff1a;01 01 00 01 00 08 6C 0C 从机回复: 01 01 01 2F 10 54 主机解析&#xff1a;01 地址(设备ID)&#xff1b; 01 功能码&#xff1b;00 01 代表查询的起始线圈地址&#xff0c;即…

二叉树题目:输出二叉树

文章目录 题目标题和出处难度题目描述要求示例数据范围 前言解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;输出二叉树 出处&#xff1a;655. 输出二叉树 难度 6 级 题目描述 要求 给定二叉树的根结点 root \textt…

链接未来:深入理解链表数据结构(一.c语言实现无头单向非循环链表)

在上一篇文章中&#xff0c;我们探索了顺序表这一基础的数据结构&#xff0c;它提供了一种有序存储数据的方法&#xff0c;使得数据的访 问和操作变得更加高效。想要进一步了解&#xff0c;大家可以移步于上一篇文章&#xff1a;探索顺序表&#xff1a;数据结构中的秩序之美 今…

06.仿简道云公式函数实战-前瞻

1.前言 在上篇文章中&#xff0c;我们介绍了QLExpress的进阶知识&#xff0c;扩展操作符&#xff0c;自定义操作符和自定义函数等内容。学了上面的内容后&#xff0c;目前对于QLExpress使用已经问题不大&#xff0c;从这篇文章&#xff0c;我们就进入我们的主题仿简道云公式函…

CentOS:Docker容器中安装vim

在使用docker容器时&#xff0c;里边没有安装vim时&#xff0c;敲vim命令时提示说&#xff1a;vim: command not found 这个时候就须要安装vim&#xff0c;安装命令&#xff1a; apt-get install vim 出现以下错误&#xff1a; 解决方法&#xff1a; apt-get update 这个命令的…

Spark中使用scala完成数据抽取任务 -- 总结

如题 任务二&#xff1a;离线数据处理&#xff0c;校赛题目需要使用spark框架将mysql数据库中ds_db01数据库的user_info表的内容抽取到Hive库的user_info表中&#xff0c;并且添加一个字段设置字段的格式 第二个任务和第一个的内容几乎一样。 在该任务中主要需要完成以下几个阶…