C++:string类(第二章)

hello,各位小伙伴,本篇文章跟大家一起学习《C++:string类》,感谢大家对我上一篇的支持,如有什么问题,还请多多指教 !
如果本篇文章对你有帮助,还请各位点点赞!!!
在这里插入图片描述

话不多说,开始进入正题

🚀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类(第二章)》的学习就先到这里,如果有什么问题,还请指教指教,希望本篇文章能够对你有所帮助,我们下一篇见!!!

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

请添加图片描述

  • 57
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 74
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 74
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值