C++:string类(第二章)

Sherry_iyao 2024-06-15 15:05:04 阅读 84

hello,各位小伙伴,本篇文章跟大家一起学习《C++:string类》,感谢大家对我上一篇的支持,如有什么问题,还请多多指教 !

如果本篇文章对你有帮助,还请各位点点赞!!!

在这里插入图片描述

话不多说,开始进入正题

文章目录

:rocket:sort函数:rocket:string类对象的修改操作:airplane:1.push_back:airplane:2.append:airplane:3.insert:airplane:4.assign:airplane:5.operator+=:airplane:6.c_str:airplane:7.find:airplane:8.rfind:airplane:9.substr:airplane:小笔记 :rocket:string类对象的容量操作:airplane:1.reverse:airplane:2.resize

🚀sort函数

sort函数是用来排序的函数,但是,sort不仅仅是排序字符或者数字。

template

void sort (RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class Compare>

void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

sort被包含在<algorithm>头文件里

可以看到sort是通过迭代器来对所有的容器进行排序,而且给出来是函数模板,也就是说可以传各种类型的迭代器,当然也是有要求的,要求是随机迭代器(以后会讲)。

传参为迭代区间,在C++里有一个要求,但凡是迭代区间,都是需要左闭右开(即 [first,last)),所以last不是一个有效数据,代码举例:

#include<algorithm>int main(){ string s = "sijghrywunbpmkzhg";cout << s << endl << endl;sort(s.begin(), s.end());cout << s << endl;}

想对数据哪一段排序就控制迭代器区间,一定要记住左闭右开。

🚀string类对象的修改操作

✈️1.push_back

void push_back (char c);

尾插一个字符,举例代码:

int main(){ string s = "hello world";cout << s << endl << endl;s.push_back('a');cout << s << endl;}

✈️2.append

1.🔥

string& append (const string& str);

尾插一个string类对象

string s1 = "hello ";string s2 = "world";s1.append(s2);

2.🔥

string& append (const string& str, size_t subpos, size_t sublen);

尾插一个string类对象的一部分

string s1 = "hello ";string s2 = "world";s1.append(s2, 2, 3);

3.🔥

string& append (const char* s);

尾插一个字符串

string s1 = "hello ";const char* s2 = "world";s1.append(s2);

4.🔥

string& append (const char* s, size_t n);

尾插一个字符串中的前几个字符

string s1 = "hello ";const char* s2 = "world";s1.append(s2, 3);

5.🔥

string& append (size_t n, char c);

尾插nc字符

string s1 = "hello ";char ch = 'a';s1.append(3, ch);

6.🔥

template string& append (InputIterator first, InputIterator last);

迭代器区间传参方式,要记住左闭右开

string s1 = "hello ";string s2 = "world";cout << s1 << endl << endl;s1.append(s2.begin(),s2.end());cout << s1 << endl;

✈️3.insert

在指定位置插入字符或者字符串。

string (1)

string& insert (size_t pos, const string& str);

substring (2) string& insert (size_t pos, const string& str, size_t subpos, size_t sublen); c-string (3) string& insert (size_t pos, const char* s); buffer (4) string& insert (size_t pos, const char* s, size_t n); fill (5) string& insert (size_t pos, size_t n, char c); void insert (iterator p, size_t n, char c); single character (6) iterator insert (iterator p, char c); range (7) template void insert (iterator p, InputIterator first, InputIterator last);

代码写法与C++:string(第一章)里所讲的string初始化类似。

但是insert的时间复杂度为O(N),因为需要挪动数据,所以能少用就少用。

✈️4.assign

为字符串指定一个新值,替换其当前内容。(相当于重新赋予一个值)

在这里插入图片描述

但是一般很少用,了解一下即可。

✈️5.operator+=

string (1)

string& operator+= (const string& str);

c-string (2)

string& operator+= (const char* s);

character (3)

string& operator+= (char c);

在字符串后追加字符串str或者字符ch。

操作很简单,如:

string str = "hello ";char ch = 'a';str += ch;

✈️6.c_str

const char* c_str() const;

返回C格式字符串。

返回一个指向数组的指针,该数组包含一个以null结尾的字符序列(即C字符串),表示字符串对象的当前值。此数组包含组成字符串对象值的相同字符序列,加上末尾的附加终止null字符(“\0”)。

代码例子:

string s1 = "abcd";const char* ch = s1.c_str();while (*ch != '\0'){ cout << *ch;++ch;}

要注意:可以看到s1.c_str()返回的是const char*的指针,所以是不能对其进行修改的。

✈️7.find

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

string (1) //找string类

size_t find (const string& str, size_t pos = 0) const;

c-string (2) //找字符数组

size_t find (const char* s, size_t pos = 0) const;

buffer (3) //在字符串中搜索指定的子字符串

size_t find (const char* s, size_t pos, size_t n) const;

character (4) //找字符

size_t find (char c, size_t pos = 0) const;

str为要找的字符串pos为寻找的起始位置(下标)s为字符指针(指向的字符串)

代码例子:

string s1 = "hello";const char* s2 = "lloododo";//寻找s2前两个字符组成的字符串在s1中的位置int index = s1.find(s2, 0,2);cout << index << endl;

✈️8.rfind

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

string (1)

size_t rfind (const string& str, size_t pos = npos) const;

c-string (2)

size_t rfind (const char* s, size_t pos = npos) const;

buffer (3)

size_t rfind (const char* s, size_t pos, size_t n) const;

character (4)

size_t rfind (char c, size_t pos = npos) const;

find不同的是,rfind是从后面开始往前找,代码例子:

string s1 = "hello";char ch = 'l';int index = s1.rfind(ch, s1.length()-1);cout << index << endl;

要注意:输出结果为3,也就是rfind找的是从后面往前第一次出现的下标位置。

✈️9.substr

string substr (size_t pos = 0, size_t len = npos) const;

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

代码举例:

string s1 = "hello";string s2 = s1.substr(0, 3);cout << s2 << endl;

✈️小笔记

1. 在string尾部追加字符时,s.push_back© / s.append(1, c) / s += 'c’三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。

2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

🚀string类对象的容量操作

✈️1.reverse

void reserve (size_t n = 0);

功能:请求字符串容量适应最大长度为n个字符的计划大小更改(主要是为字符串预留空间),代码如下:

int main(){ string s1("abcd");cout << "capacity-> " << s1.capacity() << endl;cout << "size-> " << s1.size() << endl << endl;s1.reserve(20);cout << "capacity-> " << s1.capacity() << endl;cout << "size-> " << s1.size() << endl;return 0;}

可以看到s1capacity发生了改变,但是size没有发生改变,是因为reverse是只改变capacity的。

还要注意的一点是:reverse给与的空间可能会比你所给的大,是因为在分配空间时,不同编译器会有不同的方式来扩容。

抛出一个问题:如果我们传入的空间比原来的小,会发生缩容吗?

如下测试代码:

int main(){ string s1("abcdxxxxxxxxxxxxxxxxxxxxxxxxx");cout << "capacity-> " << s1.capacity() << endl;s1.reserve(100);cout << "capacity-> " << s1.capacity() << endl;s1.reserve(10);cout << "capacity-> " << s1.capacity() << endl;return 0;}

在VS2022编译器下是不会的:

在这里插入图片描述

但是在VS2019是会发生缩容的,所以,是否缩容其实是取决于编译器的。

✈️2.resize

void resize (size_t n);

void resize (size_t n, char c);

将字符串的大小调整为n个字符的长度,

如果n小于当前字符串长度,则当前值将缩短为其第一个n个字符,删除第n个字符之后的字符。

如果n大于当前字符串长度,则通过在末尾插入所需数量的字符以达到n的大小来扩展当前内容。如果指定了c,则将新元素初始化为c的副本,否则,它们是值初始化字符(null字符)。

代码如下:

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

可以看到s1size变大了,并且capacity也变大了,很容易理解,因为s1变大,所需要的存储空间自然也就要变大,假如代码这样写:

int main(){ string s1("abcdxxxxxxxxxxxxxxxxxxxxxxxxx");cout << "size-> " << s1.size() << endl;cout << "capacity-> " << s1.capacity() << endl << endl;s1.resize(100, 'a');cout << "size-> " << s1.size() << endl;cout << "capacity-> " << s1.capacity() << endl;return 0;}

在这里插入图片描述

不够,那就a来补,因为在传参时第二个参数传了a

代码是这样:

int main(){ string s1("abcdxxxxxxxxxxxxxxxxxxxxxxxxx");cout << "size-> " << s1.size() << endl;cout << "capacity-> " << s1.capacity() << endl << endl;s1.resize(100,'a');cout << "size-> " << s1.size() << endl;cout << "capacity-> " << s1.capacity() << endl;cout << s1 << endl << endl;s1.resize(10);cout << "size-> " << s1.size() << endl;cout << "capacity-> " << s1.capacity() << endl;cout << s1 << endl;}

在这里插入图片描述

是的,s1中下标为size_t n - 1代码中为10 - 1)以后的字符会被删除。

s1的大小被缩小,所以s1的数据只能被裁剪,导致数据丢失。

你学会了吗?

好啦,本章对于《C++:string类(第二章)》的学习就先到这里,如果有什么问题,还请指教指教,希望本篇文章能够对你有所帮助,我们下一篇见!!!

如你喜欢,点点赞就是对我的支持,感谢感谢!!!

请添加图片描述



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。