【C++】C++ STL 探索:String的使用与理解(二)

简介: 【C++】C++ STL 探索:String的使用与理解

【C++】C++ STL 探索:String的使用与理解(一)https://developer.aliyun.com/article/1617331


四、string类对象的访问

关于string类对象的访问,关键掌握operator[]就行。剩下三个不如operator[]好用,其中front、back是为了规范性才实现的。

4.1 operator[]

int main()
{
  string str1("hello world");
  for (int i=0;i<str1.size();i++)
  {
    //cout << str1.operator[](i) << endl;
    cout << str1[i] << endl;
  }
  const string str2("hello world");
  for (int i = 0; i < str2.size(); i++)
  {
    //str2[i]++; const修饰的话,没有修改的权限
    cout << str2[i] << endl;
  }
  return 0;
}

五、string类对象的遍历操作

函数名称 功能说明
operator[] (重 点) 返回pos位置的字符,const string类对象调用
begin+ end begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器
rbegin + rend begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器
范围for C++11支持更简洁的范围for的新遍历方式

string类对象三种遍历方式:

  1. for+[]
  2. 范围for(本质还是迭代器)
  3. 迭代器(begin(),end())

这个三种遍历方式不仅可以遍历string对象,还能遍历修改string中的字符

注意:在string遍历时使用最多的是for+下标方括号[]或者范围for(C++11后才支持)。begin()+end()大多数使用在需要使用STL提供的算法操作string时,比如:采用reverse逆置string。

第一种:for+下标方括号[]

int main()
{
  string str1("hello world");
  int sz = str1.size();
  for (int i = 0; i < sz; i++)
  {
    //cout<<str1.operator[](i)<<endl;
    cout << str1[i] << endl;
  }
  return 0;
}

第二种:范围for

int main()
{
  string str1("hello world");
  int sz = str1.size();
  for (auto ch : str1)//从str1读取字符给变量ch,auto会自动识别类型
  {
    cout << ch << endl;
  }
  return 0;
}

接下来单独介绍下迭代器

六、迭代器(简单介绍)

6.1 迭代器概念

迭代器(Iterator)是一种用于遍历容器(如列表、字典、集合等)元素的对象。它提供了一种统一的访问容器内部元素的方式,而不必暴露容器的具体实现细节。迭代器通常用于循环结构中,让程序员能够逐个访问容器中的元素。

int main()
{
  string str1("hello world");
  string::iterator it = str1.begin();
  while (it != str1.end())
  {
    cout << *it << endl;
    it++;
  }
  return 0;
}

虽然推荐使用上面两种方式,但是迭代器才是主流。对于链表、树等数据结构,迭代器不在乎底层实现,是通用的遍历容器。迭代器是一种像指针的东西,他可以是指针也可以不是指针,具体还是看不同编译器的底层实现,迭代器有两种类型分别:可读可修改,可读不可修改

在string中定义迭代器:

string::iterator it = str1.begin();

string::iterator it = str1.end();

简单说明

begin()返回指向第一个位置的迭代器或指针,可以用于访问第一个位置元素,而end()返回指向最后一个位置之后的迭代器,它指向的是标记字符串的结尾。

可以使用容器类型的迭代器类型来声明变量:std::vector容器,begin()和end()返回的是str::vector::iterator类型的迭代器,可以将其存储相应的变量中。

总之,存储迭代器的变量类型应该与容器的迭代器类型相匹配,以确保类型的一致性,避免编译器报错或者意外行为

6.2 反向迭代器(reverse_iterator)

反向迭代器定义:string::reverse_iterator

int main()
{
  string str1("hello world");
  string::reverse_iterator rit = str1.rbegin();
  while (rit != str1.rend())
  {
    cout << *rit << "";
    ++rit;
  }
  cout << endl;
  return 0;
}

说明:rbegin()返回逆向迭代器位置,由于本来就是倒置的,++就是向前遍历。实际上很少使用场景,正向迭代器也可以满足倒着遍历的需求。

七、Modifiers(string类对象的修改操作)

函数名称 功能说明
push_back 在字符串后尾插字符c
append 在字符串后追加一个字符串
operator+= (重点) 在字符串后追加字符串str
c_str(重点) 返回C格式字符串
find + npos(重点) 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr 在str中从pos位置开始,截取n个字符,然后将其返回

对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好,减少扩容次数,提高性能

7.1 push_back

int main()
{
  string str1;//定义一个string类对象
  for (int i = 0; i < 10; i++)
  {
    str1.push_back('c');
  }
  cout << str1 << endl;
  return 0;
}

功能:将一个字符尾插到字符串中

疑问:push_back也不常用,既然支持一个字符尾插,为什么不顺便支持字符串。需要实现个支持字符串的接口,两个接口放在一起显得冗余

7.2 append

int main()
{
  string str1;
  str1.append("hello world");
  cout << str1 << endl;
  return 0;
}

功能:在字符串后追加一个字符串

对于append有很多个函数重载,这里只需要记住经常使用的就行了,其他了解下即可,但是无论是push_back,还是append,我们都不喜欢使用的,比较喜欢使用operator+=

7.3 operator+=(重要)

int main()
{
  string str1,str2;
  str1 += 'c';
  cout << str1 << endl;
  str2 += "hello world";
  cout << str2 << endl;
  str2 += str1;
  cout << str2 << endl;//输出结果:hello worldc
  return 0;
}

注意:虽然str1.push_back('c')、str1.append(1,'c')、str1+='c'三种的实现逻辑差不多,但是一般情况string类使用operator+=操作比较多,在于+=操作不仅可以连接单个字符,还可以连接字符串

7.4 assign

int main()
{
  string str1("hello world");
  str1.assign("xxx");
  cout << str1 << endl;//xxx
  return 0;
}

:将空间中数据清空再添加所需内容,就是赋值的意思。如果出现空间不足问题,会自动扩容满足当前空间需求。

7.5 insert

int main()
{
  string str1("hello world");
  str1.insert(2, "xxx");
  cout << str1 << endl;//hexxxllo world
  return 0;
}

功能:从某个位置开始插入字符

7.6 erase

int main()
{
  string str1("hello world");
  str1.erase(0, 3);
  cout << str1 << endl;
  str1.erase();
  cout << str1 << endl;
  return 0;
}

功能:从某个位置开始删除len个字符。如果需删除字符超过size,则有多少删多少

如果没有给具体需要删除几个字符,采用缺省值npos,默认全部删除。留下一行空格表示,当前空间没有释放。

7.7 replace

int main()
{
  string str1("hello world");
  str1.replace(5, 1, "%");
  cout << str1 << endl;//hello%world
  return 0;
}

功能:在字符串中某个区间位置的字符进行字符替换

小结:对于insert、erase、replace来说,底层逻辑是挪动数据,时间复杂度很高,效率很低,能不使用就不使用,建议多使用operator+=。

7.8 find

返回值:如果找到相对应的字符后,find会返回该字符所在的索引位置(从0开始的下标索引位置),如果没有匹配成功,find则会返回npos(-1);

7.8.1 size_t find(const char* s, size t pos = 0) const

size_t find(const char* s, size t pos = 0) const;
int main()
{
  string str1("file.cpp");
  size_t pos = str1.find('.');
  cout << pos << endl;
  return 0;
}

功能:find从pos开始位置,查找字符串中所需字符所在位置

7.8.2 size t find(char c,size t pos =0) const

int main()
{
  string str1("https://cplusplus.com/reference/string/string/find/");
  size_t pos = str1.find("://", 2);
  cout << pos << endl;
  return 0;
}

功能:find从pos开始位置,查找字符串中所需字符串位置,并返回开头字符的下标


【C++】C++ STL 探索:String的使用与理解(三)https://developer.aliyun.com/article/1617333

相关文章
|
1天前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
21 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
1天前
|
存储 算法 C++
C++ STL 初探:打开标准模板库的大门
C++ STL 初探:打开标准模板库的大门
35 9
|
1天前
|
安全 测试技术 C++
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化2
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化
18 6
|
1天前
|
安全 测试技术 C++
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化1
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化
18 7
|
1天前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
23 5
|
1天前
|
安全 C语言 C++
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
18 4
|
1天前
|
编译器 C语言 C++
【C++篇】解密 STL 动态之魂:全面掌握 C++ vector 的高效与优雅
【C++篇】解密 STL 动态之魂:全面掌握 C++ vector 的高效与优雅
17 3
|
1天前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
18 2
|
1天前
|
存储 编译器 程序员
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
17 2
|
1天前
|
C++
【C++】C++ STL 探索:List使用与背后底层逻辑(三)
【C++】C++ STL 探索:List使用与背后底层逻辑