当前位置: 首页 > news >正文

【C++】STL容器-string的遍历


1.引言

C++ STL(Standard Template Library)作为C++标准库的核心部分,其重要性不言而喻。它提供了一系列高效、灵活且可复用的数据结构和算法,极大地提升了开发效率,并使得代码更加易于阅读和维护。

在STL中,string容器是一个至关重要的组成部分,它专为处理字符串而设计,提供了丰富的字符串操作功能。

遍历string容器是处理字符串时的基本需求,它允许我们逐一访问和操作字符串中的每个字符,支持复杂的字符串分析任务,并可通过选择合适的遍历方法来优化程序性能。

2.string容器的基本特性

2.1string的定义与初始化

常用的实例化string 对象方式

	//默认构造string s1;//带参构造string s2("hello world");//隐示类型转换string s3="hello world";//拷贝构造string s4 = s1;//与string s4(s1);等价

3.遍历string容器的常用方法

3.1使用下标访问遍历

(1)代码示例:

	//下标+[]for (int i = 0; i < s1.size(); i++){cout << s1[i] << " ";}cout << endl;

(2)补充:size()函数是计算字符串长度的成员函数

(3)使用下标遍历实际是调用了运算符重载函数operator[]

函数原型

3.2使用std::string的成员函数at遍历

和下标遍历的方式相似但它允许通过索引访问字符串中的字符,同时提供边界检查。如果试图访问一个超出字符串范围的索引,at函数会抛出一个std::out_of_range异常。

(1)函数原型

(2)代码示例:

// at函数遍历
for (int i = 0; i < s1.size(); i++)
{cout<<s1.at(i)<<" ";
}
cout << endl;


3.3使用迭代器遍历

在C++中,迭代器是一种用于遍历容器(如std::string)的对象。迭代器提供了对容器元素的访问,并且可以用于读取或修改容器中的元素。使用迭代器遍历std::string时,你可以通过迭代器访问字符串中的每个字符。

(1)代码示例

//迭代器
string::iterator it = s1.begin();
while (it != s1.end())
{cout << *it << " ";++it;
}
cout << endl;
string::const_iterator it1 = s2.begin();
while (it1 != s2.end())
{cout << *it << endl;++it;
}
cout << endl;

在示例中声明了一个string::iterator类型的迭代器it和一个string::const_iterator类型it1(区别稍后细说)在这里可简单将it和it1看做指针

并将it初始化为s1.begin(),使用循环遍历字符串,直到it!=s1.end();

s1.begin()指向字符串的初始位置(第一个字符的位置),s1.end()指向字符串最后一个位置的下一个位置

(2)函数原型

(3)位置示意图

(4)string::iterator和string::const_iterator的区别

主要体现在对字符串元素的修改权限上:

string::iterator:允许通过迭代器修改字符串中的元素。
string::const_iterator:不允许通过迭代器修改字符串中的元素,只能用于访问。

类比指针可以帮助理解

3.4使用范围基于的for循环遍历(C++11及之后版本)

底层实际使用的是迭代器

//范围for
for (auto& ch : s1)//自动取s1里面的字符自动++
{cout << ch << " ";
}


3.5使用std::for_each算法遍历

用std::for_each算法遍历std::string时,可以传递一个lambda表达式或者函数对象作为操作,该函数将对字符串中的每个字符执行操作。std::for_each算法接受两个迭代器参数,分别指向要遍历的范围的开始和结束(左闭右开),以及一个函数参数,该函数将对范围内的每个元素执行。

(1)函数原型

template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);

这里,first和last是定义要遍历范围的迭代器,f是对每个元素执行的函数。

(2)下面是一个使用std::for_each算法遍历std::string的示例代码:

#include <iostream>
#include <string>
#include <algorithm>int main() {std::string str = "Hello, World!";// 使用 std::for_each 遍历字符串std::for_each(str.begin(), str.end(), [](char c) {std::cout << c << ' ';});std::cout << std::endl;return 0;
}


在这个示例中,std::for_each接受三个参数:str.begin()和str.end()是std::string的迭代器,它们定义了要遍历的范围;第三个参数是一个lambda表达式,它接受一个char类型的参数并打印它。这个lambda表达式将对字符串中的每个字符执行。

(3)补充:

lambda表达式是一种匿名函数,它允许快速定义单行的小函数,通常用于需要函数对象的地方。

lambda表达式的语法结构在C++中相对简单明了。它通常遵循以下格式:


[ capture ] ( parameters ) -> return_type {
    // 函数体
}

然而,并非所有部分都是必需的。在很多常见情况下,lambda表达式可以被大幅简化。例如,当不需要捕获任何外部变量,且函数体较为简短时,可以省略捕获列表和返回类型,甚至参数列表也可以省略(这种情况下,lambda表达式将没有参数)。

一个最基本的lambda表达式,不接受参数且不执行任何操作,可以是这样:
[]() { };

若需要向lambda表达式传递参数,并希望其返回特定类型的值,可以如此定义:


[](int x, int y) -> int {
    return x + y;
};

在C++11及之后的版本中,如果lambda表达式的函数体仅包含一个return语句,且此语句用于返回某个表达式的值,那么可以进一步简化,省略return关键字及花括号:


[](int x, int y) -> int { return x + y; }
// 可简化为
[](int x, int y) -> int { x + y }
// 在C++11及以后版本中,甚至可以进一步简化为
[](int x, int y) { return x + y; }
// 或
[](int x, int y) { x + y }

最后,如果lambda表达式的返回类型可以被编译器明确推断出来,那么返回类型也可以省略:
[](int x, int y) { return x + y; }

欢迎各位大佬一起学习交流~

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • pdf删除一页怎么删除?5种方法详细讲解,pdf删除页面实用技巧分享!
  • 网站收集-
  • 汽车免拆诊断案例 | 沃尔沃V40 1.9TD断续工作
  • QT绘图控件
  • Python中的内存池机制
  • 【C++】C++ STL 探索:List使用与背后底层逻辑
  • 坐牢第三十六天(QT)
  • Python编程实例-正则表达式在数据清洗中的使用技巧
  • Unity6的GPUDriven渲染到底是什么?
  • 基于CNN卷积神经网络迁移学习的图像识别实现
  • 【Linux 从基础到进阶】自动化备份与恢复策略
  • Ubuntu增强功能
  • Unity基本操作
  • HTTP 请求方式`application/x-www-form-urlencoded` 与 `application/json` 怎么用?有什么区别?
  • 【十年Java搬砖路】解决防火墙打开无法重启docker
  • 【Leetcode】101. 对称二叉树
  • 03Go 类型总结
  • 345-反转字符串中的元音字母
  • CSS盒模型深入
  • E-HPC支持多队列管理和自动伸缩
  • ES10 特性的完整指南
  • gcc介绍及安装
  • JavaWeb(学习笔记二)
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • python 装饰器(一)
  • spring boot下thymeleaf全局静态变量配置
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 技术胖1-4季视频复习— (看视频笔记)
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 限制Java线程池运行线程以及等待线程数量的策略
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #pragma once与条件编译
  • (~_~)
  • (175)FPGA门控时钟技术
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (九)One-Wire总线-DS18B20
  • (转)setTimeout 和 setInterval 的区别
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .NET NPOI导出Excel详解
  • .NET 项目中发送电子邮件异步处理和错误机制的解决方案
  • ??在JSP中,java和JavaScript如何交互?
  • ?php echo ?,?php echo Hello world!;?
  • @property @synthesize @dynamic 及相关属性作用探究
  • [202209]mysql8.0 双主集群搭建 亲测可用
  • [Android]使用Android打包Unity工程
  • [AutoSAR 存储] 汽车智能座舱的存储需求
  • [Bzoj4722]由乃(线段树好题)(倍增处理模数小快速幂)
  • [Deep Learning] 神经网络基础
  • [Effective C++读书笔记]0012_复制对象时勿忘其每一部分
  • [G-CS-MR.PS02] 機巧之形2: Ruler Circle
  • [go] 迭代器模式
  • [Golang] go-kit 介绍和使用 (微服务实现工具)
  • [hive] 窗口函数 ROW_NUMBER()