【C++入门】string类常用方法(万字详解)
目录
- 1.STL简介
- 1.1什么是STL
- 1.2STL的版本
- 1.3STL的六大组件
- 1.4STL的缺陷
- 2.string类的使用
- 2.1C语言中的字符串
- 2.2标准库中的string类
- 2.3string类的常用接口说明 (只讲解最常用的接口)
- 2.3.1string类对象的常见构造
- 2.3.2 string类对象的容量操作
- 2.3.3string类对象的修改操作
- 2.3.4 `resize`和`reserve`
- 2.3.5迭代器(正向)
- 2.3.6 反向迭代器
- 2.3.7const迭代器(正向&反向)
- 2.3.8 元素访问
- 2.3.9 `insert`和`erase`
- 2.3.10 replace、find、rfind、substr
- 2.3.11 string::swap
- 2.3.12 c_str
- 2.3.13 getline
- 2.4 总结
1.STL简介
1.1什么是STL
STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。
1.2STL的版本
- 原始版本
Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使用。
HP 版本——所有STL实现版本的始祖。
- P.J.版本
由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低,符号命名比较怪异。
- RW版本
由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一般。
- SGI版本
由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版本。被GCC(Linux)采用,可移植性好, 可公开、修改甚至贩卖,从命名风格和编程风格上看,阅读性非常高。我们后面学习STL要阅读部分源代码, 主要参考的就是这个版本。
1.3STL的六大组件
六大组件暂先了解,后面会慢慢学习。
1.4STL的缺陷
- STL库的更新太慢了。这个得严重吐槽,上一版靠谱是C++98,中间的C++03基本一些修订。C++11出来已经相隔了13年,STL才进一步更新。
- STL现在都没有支持线程安全。并发环境下需要我们自己加锁。且锁的粒度是比较大的。
- STL极度的追求效率,导致内部比较复杂。比如类型萃取,迭代器萃取。
- STL的使用会有代码膨胀的问题,比如使用vector/vector/vector这样会生成多份代码,当然这是模板语法本身导致的。
2.string类的使用
2.1C语言中的字符串
C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数, 但是这些库函数与字符串是分离开的,不太符合OOP思想(面向对象思想),而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
2.2标准库中的string类
string类其实是一个类模版实例化出来的模版类
string类的文档介绍
我们可以看到,它其实是basic_string
这个类模板实例化出来的类的一个typedef。
这里,
basic_string
实例化出来的模板类除了string还有三个。
它们都是basic_string这个类模板实例化出来的模板类,区别在于它们对应的模板参数的类型不同。
对于string类:其实它的底层就是一个动态的字符数组,
string就是一个char
类型的字符数组
wstring就是对应的wchar_t
的字符数组
u16string就是char16_t
的字符数组
u32string就是char32_t
的字符数组
这些不同类型的字符对应的大小也是不同的。
那么为什么要搞出这么多字符呢?
这里实际上是因为ASCll码
这里面的所有符号和字母都一个对应的ASCII码值。
实际上内存里存的并不是字母本身,而是它们对应的ASCII码值(这里以16进制显示)。
但是ASCII主要是来显示英语这些语言的,并且世界上还有很多国家,很多种语言比如现在我们要让计算机能显示中文,用ASCII码就不行了啊、。
那基于这样的原因呢,有人就又发明了Unicode——万国码(兼容ASCII):
Unicode又进行了划分,分为UTF-8
、UTF-16
、UTF-32
这些。
所以呢,为了应对这些不同的编码,就产生了这些不同的字符类型,所以就有了
basic_string
这个泛型字符串类模板,我们可以用它实例化出不同类型的字符串类。
总结:
- string是表示字符串的字符串类
- 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
- string在底层实际是:
basic_string
模板类的别名,typedef basic_string<char, char_traits, allocator> string;
- 不能操作多字节或者变长字符的序列。
- 在使用string类时,必须包含#include头文件以及using namespace std;
2.3string类的常用接口说明 (只讲解最常用的接口)
2.3.1string类对象的常见构造
(constructor)函数名称 | 功能说明 |
---|---|
string() (空字符串构造函数 默认构造函数 重点) | 构造一个空字符串,长度为零个字符 |
string(const char* s) (重点) | 用一个常量字符串来构造字符串类对象 |
string (const string& str, size_t pos, size_t len = npos) (不经常使用) | 复制 str 中从字符位置 pos 开始并跨越 len 字符的部分(如果 str 太短或 len 是string::npos,则直到 str 的末尾) |
string (const char* s, size_t n) | 拿s指向字符串的前n个字符去构造string对象 |
string (size_t n, char c) | 拿n个字符c去构造string对象 |
string (const string& str)(重点) | 拷贝构造 |
template string (InputIterator first, InputIterator last) | 迭代器之后讲解 |
下面我们开始逐个讲解:
string()
这里我们构造了一个空字符串。
- **
string (const char* s)
**
这里还支持这样写:
这里就是我们之前讲的单参数的构造函数是支持隐式类型转换的。
string (const string& str, size_t pos, size_t len = npos)
这里是拿str中的一个子串去构造string对象,这个字串是从str中下标pos位置开始,长度为len的一个字串。
如果这里的str
比较短,或者这里给的len
是string::npos
,则这个字串一直到str
的末尾。
举个简单的例子:
这里的len是30,那这里字符串的长度是不够的,比30短,但这里却不会报错,这里会取到字符串的结尾位置。
这里如果给的len
是string::npos
,也会一直到str末尾,并且这里len
会给缺省值,这个缺省值就是npos
。
这里的npos
是什么呢?
它是一个静态成员变量,值是-1,但是这里它的类型是size_t
(无符号整型),所以它在这里其实是整型的最大值。
string (const char* s, size_t n)
用s指向字符串的前n个字符去构造string对象:
string (size_t n, char c)
用n个字符c去构造string对象
string (const string& str)
拷贝构造:
2.3.2 string类对象的容量操作
size
和lengh
两者都是返回字符串长度。
这里你或许有疑问为什么功能一样却要写两个接口。
其实跟一些历史原因有关,string出现的比STL早,string严格来说是不属于STL的,它是C++标准库产生的,在STL出现之前就存在了。
string最早之前设计的就是length,但是后面STL出现之后,里面的其它数据结构用的都是size,那为了保持一致,就给string也增加了一个size。
因此size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
max_size
它的作用是返回字符串可以达到的最大长度
实际上字符串并不能开这么长,而且在不同平台下这个值是不一样。
capacity
这里就是返回当前string对象的容量(即当前给它分配的空间有多大,以字节表示)
==这里它是不包含给’\0’的空间的,因为它认为’\0’不是有效字符。
其他的老铁可以暂时结合文档看一下,重要的之后会给大家进行讲解。
2.3.3string类对象的修改操作
push_back
顾名思义push_back
是尾插(追加1个字符)的意思。
append
如果想追加一个字符串就可以用append
这里重载了很多版本,但是最常用的呢其实还是直接去追加一个字符串
operator+=
实际上平常我们并不喜欢用push_back
和append
。而是去用operator+=
。
string重载了+=
(运算符重载之前文章有讲过),用起来非常方便
2.3.4 resize
和reserve
有了以上的知识我们回头再看 一下容量中的resize
和reserve
。
在此之前我们观察一下,对于一个string对象,在不断插入数据的过程中它是如何进行扩容的。
int main()
{string s;size_t sz = s.capacity();cout << "capacity changed: " << sz << '\n';for (int i = 0; i < 100; ++i){s.push_back('c');if (sz != s.capacity()){sz = s.capacity();cout << "capacity changed: " << sz << '\n';}}return 0;
}
这里在VS code上几乎每次扩容都是2倍扩。
在这里简单了解过扩容机制之后,我们来看一下
reserve
。reserve
可以帮助我们更改容量大小,这样如果我们知道需要多大的空间,就可以一次开到位,就不用再一次一次的扩容了。
我们现在指定reserve100个容量,它不一定开的就是100,可能由于对齐啊等等的一些原因,它会给你多开一些空间,但是肯定不会比100小。
如果我们知道需要多少空间,reserve就可以帮助我们提前开辟好空间,然后就可以减少扩容,提升效率。
那resize
又有什么作用呢?
resize
不仅可以开空间,而且还能对开好的空间进行初始化。
这里我们没有指定第二个参数,既要填入的字符,默认给的是\0
,当然我们也可以自己指定要填入的字符:
>
如果我们传的n小于当前字符串长度,它还可以帮我们删除多出来的内容:
注意这里只会改变size
,capacity
并没有改变。
一般情况下是不会轻易缩容的,缩容的话一般是不支持原地缩的,由于底层内存管理的一些原因,是没法原地缩的。
如果支持原地缩,是不是就要支持释放一部分,我们申请一块空间,不用了只释放其中的一部分。
但是是不支持只释放一部分的,就像我们free是不是要求传的指针必须是指向其实位置的。
所以如果真的要缩容的话,只能异地缩,就是开一块新的小空间,把需要的数据拷贝过去,然后把原空间释放掉。所以缩容是要付出性能的代价的,系统原生是不支持的,我们需要自己去搞。所以不到万不得已不要轻易缩容。
2.3.5迭代器(正向)
现在我们想遍历一个string对象,首先可以循环用
[ ]
遍历,因为string是重载了[ ]
的,或者我也可以用范围for。除了这些方法外我们还可以用迭代器。
我们举个简单的例子:
int main()
{string s1("hello world");string::iterator it = s1.begin();while (it != s1.end()){cout << *it << " ";it++;}return 0;
}
这里的it就是我们定义的一个string类的迭代器(string::iterator
是类型),现阶段呢,大家可以认为迭代器是一个像指针一样的东西(不一定是指针)。
这里的begin,会返回指向字符串第一个字符的迭代器。
这里的end会返回指向最后一个字符后面位置的迭代器。
我们可以理解成这样两个位置的指针:
2.3.6 反向迭代器
迭代器除了像上面那样支持正向从前向后遍历,也支持反向遍历,反向遍历的叫做反向迭代器。
这里的rbegin()返回指向字符串最后一个字符的反向迭代器。
这里的rend()返回一个反向迭代器,迭代器指向字符串第一个字符的前一个。
下面我们再来看之前的例子:
int main()
{string s1("hello world");string::reverse_iterator it = s1.rbegin();while (it != s1.rend()){cout << *it << " ";it++;}return 0;
}
2.3.7const迭代器(正向&反向)
对于const对象不能被修改,那么普通迭代器可以认为它是一个像指针一样的东西,那我们对它解引用就不可以修改它,所以这里我们就不能用普通迭代器,会造成权限放大。
我们看到begin()
,如果是const对象调用begin,那么返回的是const迭代器const_iterator,普通迭代器可以读改数据,但是const迭代器就只能读,不能修改。
const反向迭代器就是const对象调用
rbegin()
和rend()
返回的迭代器const_reverse_iterator
这里C++11又提供了一套迭代器cbegin cend crbegin crend
,它们只返回const迭代器。
2.3.8 元素访问
string是重载了
[]
的,我们可以直接用:
operator[]
也是有普通版本和const版本的,普通对象调[]就返回char&
const对象就返回const char&
,不能修改。
at
作用跟[]
是一样的。但是呢,它们两个还是有区别的,区别在于:
用[]
如果越界访问的话是直接报错的,它内部是断言去判断的。at
是抛异常
back
和front
作用是返回最后一个和第一个字符,但是这个我们用[]
就能搞定,所以大家简单了解一下就行了。
2.3.9 insert
和erase
使用
insert
我们可以向string对象中插入字符和字符串:
这里insert提供了好几个版本,我们只需要掌握几个常用的就好。
现在我们想在world前面插入一个字符串hello,我们就可以考虑用这个:
第一个参数是插入的位置,第二个是插入的字符串。
现在我们想在第五个位置插入1个空格可以用这个:
我们还可以考虑使用迭代器:
注意: 对于string来说,我们不推荐频繁使用insert。因为string底层是字符数组,那我们学过数据结构知道在顺序表里插入元素需要要挪动数据,效率是比较低的。
我们再来看一下
erase
:
erase
是删除string对象里的元素。
举个简单的例子:
现在我们可以利用erase
删除后面的空格:
2.3.10 replace、find、rfind、substr
我们来看一下replace:
replace作用其实就是把字符串的一部分替换成新的内容。这里我们同样挑常用的讲解。
我们举个例子:
现在我们要把s里的空格替换成“hhh”:
我们再看一下find:
find可以在字符串里查找字串或者字符,返回对应的下标。找不到返回npos
再来举个例子:
现在想在s里查找“w”:
我们再来看rfind:
find是从前往后找第一个匹配项,rfind是从后往前找倒数第一个匹配项
我们再来看substr:
substr
可以帮助我们获取string对象中指定的一个子串。
举个例子:
这里我们获取了第六个位置开始长度为五的子串。
2.3.11 string::swap
和标准库里的swap不同的是,这里的swap接收一个string对象,与当前对象进行交换。
2.3.12 c_str
我们再来看一下
c_str
:
它的作用是返回一个指向当前string对象对应的字符数组的指针,类型为const char*。
2.3.13 getline
我们举个例子:
int main()
{string s;cin >> s;cout << s << endl;return 0;
}
现在我想输入hello world 能正常输出吗?
这里的cin,我们在用它们输入的时候是有可能输入多个值的,那当我们输入多个值的时候,它们默认是以空格或者换行来区分我们输入的多个值的。
所以我们这里输入的hello world
,会被认为是两个值以空格分隔开,所以cin值读到了空格前面的hello,后面的world就被留在缓冲区了。
我们可以用
getline
解决这种问题:
getline它读取到空格才结束,当然它还支持我们自己指定结束符。第一个参数就是接收cin,第二个参数接收我们要输入的string对象。
2.4 总结
这里关于string的常用接口就讲的差不多了,这里string的接口很多,如果后面有遇到不清楚的这里建议大家去阅读官方文档 string
相关文章:

【C++入门】string类常用方法(万字详解)
目录 1.STL简介1.1什么是STL1.2STL的版本1.3STL的六大组件1.4STL的缺陷 2.string类的使用2.1C语言中的字符串2.2标准库中的string类2.3string类的常用接口说明 (只讲解最常用的接口)2.3.1string类对象的常见构造2.3.2 string类对象的容量操作2.3.3string…...

大数据错误
question1 : Could not locate Hadoop executable: D:\hadoop-3.3.1\bin\winutils.exe - 【已解决】Could not locate executable E:\Hadoop\bin\winutils.exe in the Hadoop binaries._could not locate executable e:\hadoop-3.3.1\bin\wi_君问归期魏有期的博客-CSDN博客 q…...

【Node.js】Express-Generator:快速生成Express应用程序的利器
在Node.js世界中,Express是一个广泛使用的、强大的Web应用程序框架。它为开发者提供了一系列的工具和选项,使得创建高效且可扩展的Web应用程序变得轻而易举。然而,对于初学者来说,配置和初始化Express应用程序可能会有些困难。为了…...

SpringMVC的工作流程及入门
目录 一、概述 ( 1 ) 是什么 ( 2 ) 作用 二、工作流程 ( 1 ) 流程 ( 2 ) 步骤 三、入门实例 ( 1 ) 入门实例 ( 2 ) 静态资源处理 给我们带来的收获 一、概述 ( 1 ) 是什么 SpringMVC是一个基于Java的Web应用开发框架,它是Spring Framework的一部…...

logging.level的含义及设置 【java 日志 (logback、log4j)】
日志级别 trace<debug<info<warn<error<fatal 常用的有:debug,info,warn,error 通常我们想设置日志级别,会用到 logging.level.rootinfo logging.level设置日志级别,后面跟生效的区域。r…...

第 3 章 栈和队列(链栈)
1. 背景说明 链栈是指用单链表实现的栈,其存储结构为链式存储,实现类似于队列的链式实现,不过在插入元素时链栈在头部插入,而 链式队列在尾部插入,本示例中实现为带头结点的链栈,即栈顶元素为栈指针的下一…...

嵌入式面试-经典问题
1、c语言内存模型 2、C语言中的变量定义在什么地方 3、C语言代码如何运行的、关于栈的相关 4、指针函数与函数指针的区分 5、Static关键字的作用 6、const作用 7、进程与线程的区别 8、链表与数组的区别 9、#define宏定义与typedef的区别...

ZLMeidaKit在Windows上启动时:计算机中丢失MSVCR110.dll,以及rtmp推流后无法转换为flv视频流解决
场景 ZLMediaKit在Windows上实现Rtmp流媒体服务器以及模拟rtmp推流和http-flv拉流播放: ZLMediaKit在Windows上实现Rtmp流媒体服务器以及模拟rtmp推流和http-flv拉流播放_zlm流媒体服务器_霸道流氓气质的博客-CSDN博客 按照以上教程启动MediaServer.exe时提示&am…...

项目(智慧教室)第二部分,人机交互页面实现,
使用软件: 1.BmCvtST.exe 这是stm32Cubemx工程下的带三方软件。存在STemWin中。 作用: 图片变成.c文件格式。 2.CodeBlock 3.模拟器工程(具体请看上一节) 一。emWin环境的搭建 1.codeBlock下载 开源免费。 2.使用stm的C…...

【docker】docker的一些常用命令-------从小白到大神之路之学习运维第92天
目录 一、安装docker-ce 1、从阿里云下载docker-cer.epo源 2、下载部分依赖 3、安装docker 二、启用docker 1、启动docker和不启动查看docker version 2、启动服务查看docker version 有什么区别?看到了吗? 3、看看docker启动后的镜像仓库都有什…...

ubuntu18.04.6的安装教程
目录 一、下载并安装virtualbox virtualbox7.0.8版本的安装 二、Ubuntu的下载与安装 ubuntu18.04.6操作系统 下载 安装 一、下载并安装virtualbox VirtualBox是功能强大的x86和AMD64/Intel64虚拟化企业和家庭使用的产品。VirtualBox不仅是面向企业客户的功能极其丰富的高…...

小白的第一个RNN(情感分析模型)
平台:window10,python3.11.4,pycharm 框架:keras 编写日期:20230903 数据集:英语,自编,训练集和测试集分别有4个样本,标签有积极和消极两种 环境搭建 新建文件夹&am…...

华为云 存在部支持迁移的外键解决方法
DRS 检测出源端存在不支持的外键引用操作 MySQL、GaussDB(for MySQL)为源的全量增量或增量迁移、同步场景,以及MySQL、GaussDB(for MySQL)为源灾备场景 表1 源端存在不支持的外键引用操作 预检查项 源端存在不支持的外键引用操作。 描述 同步对象中存在包含CASC…...

C# winform控件和对象双向数据绑定
实现目的: 控件和对象双向数据绑定 实现结果: 1. 对象值 -> 控件值 2. 控件值 -> 对象值 using System; using System.Windows.Forms;namespace ControlDataBind {public partial class MainForm : Form{People people new People();public Mai…...

达梦8 在CentOS 系统下静默安装
确认系统参数 [rootlocalhost ~]# ulimit -a core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited【1048576(即 1GB)以上或 unlimited】 scheduling priority (-e) 0 file size (blocks, -f) unlimite…...

flink k8s sink到kafka报错 Failed to get metadata for topics
可能出现的3种报错 -- 报错1 Failed to get metadata for topics [...]. org.apache.kafka.common.errors.TimeoutException: Call-- 报错2 Caused by: org.apache.kafka.common.errors.TimeoutException: Timed out waiting to send the call. Call: fetchMetadata Heartbe…...

利用大模型MoritzLaurer/mDeBERTa-v3-base-xnli-multilingual-nli-2mil7实现零样本分类
概念 1、零样本分类:在没有样本标签的情况下对文本进行分类。 2、nli:(Natural Language Inference),自然语言推理 3、xnli:(Cross-Lingual Natural Language Inference) ,是一种数据集,支持15种语言,数据集包含10个领域,每个领…...

代码随想录二刷day07
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、力扣454. 四数相加 II二、力扣383. 赎金信三、力扣15. 三数之和四、力扣18. 四数之和 前言 提示:这里可以添加本文要记录的大概内容࿱…...

点云从入门到精通技术详解100篇-点云的泊松曲面重建方法
目录 前言 相关理论 2.1三维点云 2.2体素滤波 2.3隐式曲面重建 泊松曲面重建及改进...

【STM32】学习笔记(串口通信)
串口通信 通信接口硬件电路电平标准USARTUSART框图 通信接口 串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信 单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信&#…...

【Unity3D赛车游戏优化篇】新【八】汽车实现镜头的流畅跟随,以及不同角度的切换
👨💻个人主页:元宇宙-秩沅 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 秩沅 原创 👨💻 收录于专栏:Uni…...

webpack5 (四)
react-cli 中配置 开发环境 const path require(path) const EslintWebpackPlugin require(eslint-webpack-plugin) const HtmlWebpackPlugin require(html-webpack-plugin) const ReactRefreshWebpackPlugin require(pmmmwh/react-refresh-webpack-plugin); //封装处理样…...

电脑硬盘数据恢复一般需要收费多少钱
随着电子信息时代的发展,个人和企业对电脑硬盘中存储的数据越发重视。然而,由于各种原因,硬盘数据丢失的情况屡见不鲜。如果您正陷入这样的困境,您可能会好奇恢复失去的数据需要花费多少钱。本文将为您介绍电脑硬盘数据恢复的一般…...

服务运营 | MSOR文章精选:远程医疗服务中的统计与运筹(二)
作者信息:王畅,陈盈鑫 编者按 在上一期中,我们分享了与远程医疗中运营管理问题相关的两篇文章。其一发表在《Stochastic Systems》,旨在使用排队论与流体近似的方法解决远程医疗中资源配置的问题;其二发表在《Managem…...

QT(9.3)定时器,绘制事件
作业: 自定义一个闹钟 pro文件: QT core gui texttospeechgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecat…...

python opencv
保存直播流生存逐个图片 import cv2 from threading import Threadclass ThreadedCamera(object):def __init__(self, source 0):self.capture cv2.VideoCapture(source)self.thread Thread(target self.update, args ())self.thread.daemon Trueself.thread.start()sel…...

QProcess 调用 ffmpeg来处理音频
项目场景: 在文章 qt 实现音视频的分贝检测系统中,实现的是边播放变解析音频数据来统计音频的分贝大小,并不满足实际项目的需求,有的视频声音正常,有的视频声音就偏低,即使放到最大音量声音也是比较小&…...

“深入探究SpringMVC的工作原理与入门实践“
目录 引言1. 什么是SpringMVC?1.1. 模型1.2. 视图1.3. 控制器 2. SpringMVC的工作流程2.1. 客户端发送请求2.2. DispatcherServlet的处理2.3. 处理器映射器的使用2.4. 处理器的执行2.5. 视图解析器的使用2.6. 视图的渲染 3. SpringMVC的核心组件4. 弹簧MVC总结 引言 SpringMV…...

【Node.js】Node.js安装详细步骤和创建Express项目演示
Node.js是一个开源的、跨平台的JavaScript运行环境,用于在服务器端运行JavaScript代码。它提供了一个简单的API,可以用于开发各种网络和服务器应用程序。 以下是Node.js的安装和使用的详细步骤和代码示例: 1、下载Node.js 访问Node.js官方…...

栈和队列OJ
一、括号的匹配 题目介绍: 思路: 如果 c 是左括号,则入栈 push;否则通过哈希表判断括号对应关系,若 stack 栈顶出栈括号 stack.pop() 与当前遍历括号 c 不对应,则提前返回 false。栈 stack 为空࿱…...