【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; }

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

  • 32
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值