string类(3)

string类(3)

在这里插入图片描述

push_back

这是尾插一个字符。

append

这是尾插字符串。可以看出来设计得很复杂。

实践中比较常用的是:

string s("hello world");
s.push_back(' ');
s.push_back('x');
s.append("zzzzzzzz");

用得更多的是:

operator +=

实践中,string的尾插我们用+=就可以了。底层空间不够了会扩容。

assign

赋值,把之前的覆盖掉。空间不够底层也会扩容。

和operator=有一些重叠。

用得也比较少。

insert

这个接口设计也比较冗余。很多接口的实用性并没有那么强。

真正用得多的就两个:

可以看到没有提供头插。所以头插就得用insert。

但是头插或者中间插入要谨慎,因为实现效率比较低。一个是空间不够要扩容,另一个是需要把插入位置之后的数据整体后移

也可以只插入一个字符,只要用的是双引号不是单引号就行。

或者这样写(体现出混乱):

这个是先创建char对象,然后再插入,有两种方式:第一种不得不写第二个参数为1;第二种前一个是迭代器。

insert要谨慎使用,不到万不得已不要轻易用。

向前兼容,所以冗余。

erase

第一个用得最多。

还可以这样尾删:

还可以 这样尾删:

string s("hello world");
s.erase(s.size()-1,1);
cout << s << endl;

总结:

//头删
s.erase(0,1);
s.erase(s.begin());
//尾删
s.erase(--s.end());
s.erase(s.size()-1,1);

sequence (1):
string& erase (size_t pos = 0, size_t len = npos);

所以可以利用npos,全删了:

s.erase(6);

string一般只尾插,不删除,不在中间插入。可以用不同的策略提高效率。

replace

可以替换成string、string的一部分,char*、char *的一部分;可以从一个迭代器到另一个迭代器间替换,也可以从pos开始的len个字符替换。

底层是怎么做的呢?应该字符替换成两个字符,得向后挪动,空间不够还得扩容。如果是多个字符替换成更少的字符,不需要扩容但是要往前挪动数据。

这东西效率也不高。

怎么把所有的空格替换成百分号呢?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

但是每次都是从头到尾找空格,没必要。

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

while (pos != string::npos)
{
	s.replace(pos,1, "%%");
	pos = s.find( ' ',pos+2);//pos+2
}

但是如果要大量这样字符串替换,这个代码是非常不好的。因为不止一次扩容。

这时候我们就可以考虑用空间换时间。

最后可以复制拷贝:

s=tmp;

其实用swap会更高效:

s.swap(tmp);

这个交换在底层会把它俩的_str,_size,_capacity进行交换:

class string
{
    char* _str;
    size_t _size;
    size_t _capacity;
};

这个效率很高,如果我们再reserve一下,效率就更高了 :

string tmp;
tmo.reserve(s.size());
for(auto ch : s)
{
    ……
}

所以insert erase replace都要警惕其成为性能杀手。replace只在平替效率高。

关于尾删,C++11还提供了个pop_back,但是用erase尾删也可以。

c_str

功能就是返回它底层那个指向堆上空间的字符串指针。

意义是什么呢?兼容C语言。

功能就是return一个C形式的字符串。

适用于一些需要C的接口:

string file;
cin >> file;
FILE* fout = fopen(file.c_str(), "r");
char ch = fgetc(fout);
while(ch!= EOF)
{
    cout<<ch;
    ch=fgetc(fout);
}
fclose(fout);

data接口和c_str类似。

get_allocator先不用管。

copy就是拷贝一个子串过来,用得少。

find系列

我们前面已经看过find,可以找字符或者串。

rfind是倒着找。什么情况需要倒着找?比如想要获取一个文件的后缀。

但如果我们的s是"test.cpp.zip",我们只能取到cpp.zip,但我们想要的是zip。

所以我们用rfind比较合理。

find_first_of

和"abcd"中的任意一个相等就返回,替换为’*'。

所以这个接口名字比较不符合功能。

find_last_of

倒着找

find__first_not_of


然后来看看string的几个非成员函数

operator+

为什么这个+要设计成非成员函数?

因为它想要支持把string+字符串反过来,也就是字符串+string:

不过,这个+用得不是很多。

relational operators (string)


这个不多说了。

本文到此结束=_=

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值