string类详解
创始人
2024-04-03 00:23:15

文章目录

  • 1:构造string类
  • 1.1:方法
    • 1.2:测试
  • 2:size和length
    • 2.1:用途
    • 2.2:测试
  • 3:capacity
    • 3.1:用途
    • 3.2:测试
  • 4:clear
    • 4.1:用途
    • 4.2:测试
  • 5:empty
    • 5.1:用途
    • 5.2:测试
  • 6:reserve
    • 6.1:用途
    • 6.2:测试
  • 7:resize
    • 7.1:用途
    • 7.2:测试
  • 8:string的三种遍历
    • 8.1:方法一 for循环和[]重载
    • 8.2:方法二 迭代器
      • 8.2.1:const迭代器
      • 8.2.2:迭代器和[]的结论
    • 8.3范围for
  • 9:push_back
    • 9.1:功能
    • 9.2:测试
  • 10:append
    • 10.1:用法
    • 10.2:测试
  • 11:operator +=
    • 11.1:用法
    • 11.2:测试
  • 12:字符串相加例题
  • 13:reverse
    • 13.1:用法
    • 13.2:测试
  • 14:find
    • 14.1:用法
    • 14.2:测试
  • 15:rfind
    • 15.1:用法
  • 16:substr
    • 16.1:用法
  • 17:find_first_of
    • 17.1:用法
    • 17.2:测试
    • 18:erase
    • 18.1:用法
  • 19:c_str
    • 19.1:用法
    • 19.2:测试
    • 20:assign
    • 20.1:用法
    • 20.2:测试
  • 21:replace
    • 21.1:用法
    • 21.2:测试

1:构造string类

1.1:方法

  • string() :构造一个空字符串对象
  • string(const char* str) :用C-String构造对象
  • string(size_t n, char c):string类对象中包含n个c
  • string(const string& str):拷贝构造对象

1.2:测试

string test1;//构造空的string类对象
string test2("abcd");//用c-string构造string类对象
string test3(test2);//用拷贝构造函数构造

image-20221101094248937

2:size和length

2.1:用途

都是求字符串对象有效字符个数

返回值是size_t

2.2:测试

string test4("hello world");
size_t size1 = test4.size();//有效字符长度 返回值是size_t
size_t size2 = test4.length();//有效字符长度 返回值是size_t

image-20221101094506008

均为11,11位hello + 空格 + world的长度,不包含\0,而为什么会有length和size的名称差别呢,因为在数据结构中对于链表和顺序表的结构,length可以表明长度,但是在树等结构中用size可以更直观的表明大小。

3:capacity

3.1:用途

求字符串对象的容量

3.2:测试

	string str1;string str2("abc");size_t c1 = str1.capacity();size_t c2 = str2.capacity();

image-20221101095316537

4:clear

4.1:用途

清除字符串中的有效字符

4.2:测试

	string str("abcdefg");str.clear();cout << str << endl;

image-20221101095738756

什么也没有打印出来,那他的capacity有变化吗?

image-20221101095912474

容量是没有变化的,还是15,因此clear只是清空string中有效字符,不改变底层空间大小。

5:empty

5.1:用途

判断字符串是否为空,空返回true,否则返回false。

5.2:测试

	string str1("abcdefg");string str2;bool k1 = str1.empty();bool k2 = str2.empty();return 0;

image-20221101100236689

6:reserve

6.1:用途

为string对象预留空间

6.2:测试

string str("abcd");
str.reserve(20);
size_t k = str.capacity();//不预留的话是15

image-20221101100751436

容量变成了31,因此针对我们用c语言实现的数据结构中,涉及多次扩容的并且暂时知道数据容量多少的时候,先提前reserve好空间比较好。

7:resize

7.1:用途

将有效字符变成n个,查询cplusplus文档得知。

image-20221101101301572

有2种用法,用空字符填充和用指定字符填充。

既然是更改字符的数量,那么肯定有3种情况。

  • n在size和capacity中间 插入数据,闭区间
  • n<size 删除数据
  • n>capacity 扩容,补充数据

7.2:测试

	string st1("hello wjw");st1.resize(5);cout << st1.size() << endl;cout << st1.capacity() << endl;cout << st1 << endl<

st2和st3的resize差别是在于填充的字符是空字符和*的区别。

image-20221101102730810

可以看到当n<size的时候,直接返回前n个字符。不修改容量

size<=n<=capacity的时候,插入数据,不修改容量

capacity<n的时候,扩容,再插入数据。

8:string的三种遍历

8.1:方法一 for循环和[]重载

	for (size_t i = 0; i < str.size(); i++){cout << str[i] << endl;}

用[]重载

8.2:方法二 迭代器

	string::iterator it = str.begin();while (it != str.end()){cout << *it << endl;}

c++中string类中存在迭代器。begin和end获取一个字符的迭代器,begin是字符串第一个字符,end是最后一个字符的下一个位置的迭代器

同时还有反向迭代器,反向遍历。

	string::reverse_iterator rit = str.rbegin();while (rit != str.rend()){cout << *rit << endl;}

在c++11中,可以直接使用auto关键词推导迭代器类型。

	auto it = str.begin();while (it != str.end()){cout << *it << endl;}

8.2.1:const迭代器

注意以下情况,如果我们要求只读一个字符串的时候,如何使用迭代器?比如

void test(const string& str)
{string::iterator it = str.begin();while(it != str.end()){cout<<*it<

image-20221101110123317

编译器报错,说不能从const的迭代器转换到非const的迭代器。

查询文档得知。

image-20221101110231449

设计了2种迭代器。

当我们只读的时候,应使用string::const_iterator的格式

同样的针对第一种[]遍历,

image-20221101110348803

也有2种,const和非const。

	const string str("abcdefg");for (size_t i = 0; i < str.size(); i++){str[i] += 1;cout << str[i] << endl;}

当给定的是常量字符串对象,[]就会调用const类型的,如果试图修改字符串,就会报错。

image-20221101110554711

8.2.2:迭代器和[]的结论

针对只读的功能函数,设计的时候提供const版本即可

针对只写的功能函数,设计的时候提供非const版本即可

针对读写的功能函数,设计的时候提供const和非const版本

8.3范围for

	string str("abcd");for (auto ch : str){cout << ch;}

9:push_back

9.1:功能

尾插一个字符,会扩容

9.2:测试

	string str("abcd");size_t k = str.capacity();for(size_t i = 0; i < 100; i++){str.push_back('a');if (k != str.capacity()){k = str.capacity();cout << "capacity changed:" << str.capacity() << endl << endl;}}}

image-20221101113643080

每次大概是1.5倍的扩容,

10:append

10.1:用法

image-20221101114221684

在字符串末尾添加字符串

10.2:测试

	string str("abcd");str.append("hello");string str2("bit");str.append(str2);cout << str << endl;

可以追加一个字符串对象,也可以直接追加字符串。

image-20221101114505273

11:operator +=

11.1:用法

追加字符串

11.2:测试

string str("abcd");
str += "hello bit";
string str2("abcd");
str += str2;
cout << str << endl;

12:字符串相加例题

image-20221101115935772

class Solution {
public:string addStrings(string num1, string num2) {
int end1 = num1.size()-1;
int end2 = num2.size()-1;
string num3;
int carry = 0;
while(end1>=0||end2>=0)
{int sum1 = end1>=0?num1[end1]-'0':0;int sum2 = end2>=0?num2[end2]-'0':0;int ret = sum1 + sum2 + carry;carry = ret / 10;ret %= 10;num3 += ret+'0';--end1;--end2;
}
if(carry == 1)
{num3 += '1';
}
reverse(num3.begin(),num3.end());
return num3;
}
};

13:reverse

13.1:用法

逆置字符串

13.2:测试

	string str("hello wjw");reverse(str.begin(), str.end());cout << str << endl;

image-20221101121415411

是给2个迭代器,逆置2个迭代器范围内的数据。

14:find

14.1:用法

查找第一个符合的字符,并且返回他的下标

image-20221101122120680

image-20221101122159789

如果没有查找到,返回npos

image-20221101122224310

所以在查找的时候一般可以让查找值是否等于-1来判断是否找到

14.2:测试

	string str("hello wjw");size_t pos = str.find('j');if (pos != -1){cout << str[pos] << endl;}

string库实现的时候,给pos位置一个缺省值,因此如果我们只传对象的时候,默认是从下标0开始查找的。

那如何查找下一个字符呢?

	string str("woshi  woshi");size_t pos = str.find('w');while (pos != string::npos){cout << str[pos] << endl;pos = str.find('w', pos + 1);}

设置下一次查找的位置在第一次找到的pos之后一个位置即可。

15:rfind

15.1:用法

反向查找第一个符合的字符,并且返回其下标。

16:substr

16.1:用法

返回pos位置开始的后续的len个字符

image-20221101123711605

如图len是给了缺省值npos的,npos是size_t类型,因此如果我们不传参len的话,是相当于直接返回pos开始直到字符串结束的所有字符

因此比如我们想取一个文件的后缀名的时候,就可以使用这个

	string file("test.cpp");size_t pos = file.rfind('.');string str = file.substr(pos);cout << str << endl;

17:find_first_of

17.1:用法

image-20221101124352994

在string里面查找与给定的字符c或者字符串相符合的 string里面的第一个字符的下标。

17.2:测试

	string str("wo ai ni ge chou sha bi");size_t pos = str.find_first_of("oie");while (pos != string::npos){str[pos] = '*';pos = str.find_first_of("oie", pos + 1);}cout << str << endl;

image-20221101125030273

18:erase

18.1:用法

删除pos位置的字符

image-20221101125134275

第一个是删除pos位置开始,如果不给len的长度就会删除从pos位置一直到字符串结束的所有字符。

第二个是给一个迭代器,删除这个位置的字符

第三个是给2个迭代器,删除2个迭代器范围内的所有字符。

	string str("wo ai ni ge chou sha bi");//类似头删str.erase(0,1);cout << str << endl;string str("wo ai ni ge chou sha bi");str.erase(str.begin());cout << str << endl;string str("wo ai ni ge chou sha bi");str.erase(str.begin(), str.end());cout << str << endl;

在数据结构中顺序表我们学过,头删是要挪动数据的,因此我们尽量少用。时间复杂度为O(N^2)

19:c_str

19.1:用法

返回一个c语言中的数组,该数组为c字符串,包含\0

19.2:测试

string str("wo ai ni ge chou sha bi");
char* str1 = new char[str.size() + 1];
strcpy(str1, str.c_str());
cout << str1 << endl;

image-20221101130326691

20:assign

20.1:用法

将字符串全部替换为另外一个字符串的前n个,如果没有定义n,n默认为npos,相当于先clear再+=。

image-20221101133216624

20.2:测试

	string str("wo ai ni ge chou sha bi");cout << str.capacity()<< endl;str.assign("abcd");cout << str.capacity() << endl;

image-20221101132501685

如果是变小,容量不变

	string str("wo ai ni ge chou sha bi");cout << str.capacity()<< endl;str.assign("abcdadsadasdsadasdsadsadsadasd123213123213213213123213213213");cout << str.capacity() << endl;

image-20221101132556549

如果是变大,扩容。

assign相当于赋值拷贝

	string str("wo ai ni ge chou sha bi");

21:replace

21.1:用法

image-20221101132706914

从pos位置开始的len个字符替换成str

21.2:测试

	string str("wo ai ni ge chou sha bi");str.replace(3, 2, "buai");cout << str << endl;

如图就是把从第一个a开始的2个字符替换成buai。

image-20221101133617805

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...