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

池央 2024-09-15 17:05:01 阅读 78

1.引言

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

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

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

2.string容器的基本特性

2.1string的定义与初始化

常用的实例化string 对象方式

<code>//默认构造

string s1;

//带参构造

string s2("hello world");

//隐示类型转换

string s3="hello world";code>

//拷贝构造

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)代码示例:

<code>// 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及之后版本)

底层实际使用的是迭代器

<code>//范围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; }

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



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。