【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

目录
打赏
0
1
1
0
21
分享
相关文章
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
67 2
C++ String揭秘:写高效代码的关键
在C++编程中,字符串操作是不可避免的一部分。从简单的字符串拼接到复杂的文本处理,C++的string类为开发者提供了一种更高效、灵活且安全的方式来管理和操作字符串。本文将从基础操作入手,逐步揭开C++ string类的奥秘,帮助你深入理解其内部机制,并学会如何在实际开发中充分发挥其性能和优势。
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
151 73
【c++丨STL】set/multiset的使用
本文深入解析了STL中的`set`和`multiset`容器,二者均为关联式容器,底层基于红黑树实现。`set`支持唯一性元素存储并自动排序,适用于高效查找场景;`multiset`允许重复元素。两者均具备O(logN)的插入、删除与查找复杂度。文章详细介绍了构造函数、迭代器、容量接口、增删操作(如`insert`、`erase`)、查找统计(如`find`、`count`)及`multiset`特有的区间操作(如`lower_bound`、`upper_bound`、`equal_range`)。最后预告了`map`容器的学习,其作为键值对存储的关联式容器,同样基于红黑树,具有高效操作特性。
79 3
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
模拟实现c++中的string
模拟实现c++中的string
【c++丨STL】priority_queue(优先级队列)的使用与模拟实现
本文介绍了STL中的容器适配器`priority_queue`(优先级队列)。`priority_queue`根据严格的弱排序标准设计,确保其第一个元素始终是最大元素。它底层使用堆结构实现,支持大堆和小堆,默认为大堆。常用操作包括构造函数、`empty`、`size`、`top`、`push`、`pop`和`swap`等。我们还模拟实现了`priority_queue`,通过仿函数控制堆的类型,并调用封装容器的接口实现功能。最后,感谢大家的支持与关注。
118 1
|
3月前
|
【c++丨STL】stack和queue的使用及模拟实现
本文介绍了STL中的两个重要容器适配器:栈(stack)和队列(queue)。容器适配器是在已有容器基础上添加新特性或功能的结构,如栈基于顺序表或链表限制操作实现。文章详细讲解了stack和queue的主要成员函数(empty、size、top/front/back、push/pop、swap),并提供了使用示例和模拟实现代码。通过这些内容,读者可以更好地理解这两种数据结构的工作原理及其实现方法。最后,作者鼓励读者点赞支持。 总结:本文深入浅出地讲解了STL中stack和queue的使用方法及其模拟实现,帮助读者掌握这两种容器适配器的特性和应用场景。
93 21
深入浅出 C++ STL:解锁高效编程的秘密武器
C++ 标准模板库(STL)是现代 C++ 的核心部分之一,为开发者提供了丰富的预定义数据结构和算法,极大地提升了编程效率和代码的可读性。理解和掌握 STL 对于 C++ 开发者来说至关重要。以下是对 STL 的详细介绍,涵盖其基础知识、发展历史、核心组件、重要性和学习方法。
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
88 1

热门文章

最新文章