常用迭代器以及使用方法
一:迭代器的基本概念
(1)基本概念:
- STL是C++标准库的一部分,提供了丰富的模板类和算法,用于实现通用的数据结构和算法。其中,迭代器是STL的重要组成部分之一。
- 迭代器是一种抽象的概念,用于提供对容器中元素的遍历和访问。STL中的容器类(如向量、列表、映射等)都提供了相应的迭代器类型,用于操作容器中的元素。
- 通过使用迭代器,我们可以在不关心容器的具体类型的情况下,对容器的元素进行遍历、访问和修改。迭代器提供了一种统一的接口,使得算法可以在不同类型的容器上通用地操作。
(2)示例:
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
// 使用迭代器遍历容器的元素
std::cout << "Numbers: ";
for (auto it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << " "; // 输出容器的元素
}
std::cout << std::endl;
return 0;
}
在上述示例中,我们使用
std::vector<int>
定义了一个整数向量numbers
,其中包含一些整数。然后,我们使用迭代器来遍历容器的元素。 通过调用numbers.begin()
和numbers.end()
,我们获得了指向向量numbers
的起始位置和结束位置的迭代器。
这些迭代器定义了一个范围,包括需要遍历的元素。 在for
循环中,我们使用迭代器it
来遍历容器的元素。通过解引用操作符*it
,我们可以访问迭代器指向的元素值,并输出到控制台。这样,我们就使用迭代器成功地遍历了向量numbers
中的元素,并将它们输出到控制台。
需要注意的是,迭代器范围是左闭右开的,即begin()
指向的元素包含在范围内,而end()
指向的元素不包含在范围内。因此,在循环条件中,我们使用it != numbers.end()
来确保迭代器没有超过容器的结束位置。
小结:
这个示例展示了如何使用迭代器来遍历容器的元素,而不依赖于容器的具体类型和内部实现。这使得算法可以在不同类型的容器上通用地操作。
二:迭代器的主要类别
(1)迭代器按功能和特性分为五个主要类别:
- 输入迭代器(Input Iterator):允许以只读方式从容器中读取元素,并支持迭代器递增操作。输入迭代器可以按顺序读取容器的元素,但不保证能够多次遍历同一容器。
- 输出迭代器(Output Iterator):允许向容器中写入元素,并支持迭代器递增操作。输出迭代器通常用于向容器添加元素,但不保证能够多次遍历同一容器。
- 正向迭代器(Forward Iterator):结合了输入迭代器和输出迭代器的功能,既可以读取容器的元素,也可以向容器中写入元素。正向迭代器具有递增操作,可以按顺序遍历容器的元素。
- 双向迭代器(Bidirectional Iterator):在正向迭代器的基础上增加了递减操作,允许在容器中向前和向后遍历元素。双向迭代器可以向前和向后移动,但无法跳跃性地访问容器的元素。
- 随机访问迭代器(Random Access Iterator):具有最强大的功能,支持随机访问容器中的元素。随机访问迭代器可以通过迭代器的加减运算符跳跃性地访问容器的元素,还可以进行比较运算和指针算术运算。
(2)以下是一些常见的C++标准容器及其迭代器类型:
std::vector
:随机访问迭代器std::deque
:随机访问迭代器std::list
:双向迭代器std::set
、std::multiset
:双向迭代器std::map
、std::multimap
:双向迭代器std::forward_list
:正向迭代器std::unordered_set
、std::unordered_multiset
:正向迭代器std::unordered_map
、std::unordered_multimap
:正向迭代器
三:常用迭代器和操作
注意:不同容器类型支持的迭代器类型可能会有所不同。有些容器甚至可能提供自定义的迭代器类型。
(1)正向迭代器 (Forward Iterator):
示例:
std::vector<int> numbers = {1, 2, 3, 4, 5};
for (auto it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << " ";
}
(2)双向迭代器 (Bidirectional Iterator) :
示例:
std::list<int> numbers = {1, 2, 3, 4, 5};
for (auto it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << " ";
}
(3)随机访问迭代器 (Random Access Iterator):
示例:
std::vector<int> numbers = {1, 2, 3, 4, 5};
for (auto it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
auto it = numbers.begin();
std::cout << "Third element: " << *(it + 2) << std::endl;
(4)常量迭代器 (Const Iterator):
示例:
std::vector<int> numbers = {1, 2, 3, 4, 5};
for (auto cit = numbers.cbegin(); cit != numbers.cend(); ++cit) {
std::cout << *cit << " ";
}
cbegin() 和 cend() 的用法类似于 begin() 和 end(),但它们返回的是常量迭代器,用于保证容器元素的只读访问。
这在需要确保容器不被修改的情况下很有用。这对于保护容器的数据完整性和提高代码的安全性非常有帮助。
(5)反向迭代器 (Reverse Iterator):
示例:
std::vector<int> numbers = {1, 2, 3, 4, 5};
for (auto rit = numbers.rbegin(); rit != numbers.rend(); ++rit) {
std::cout << *rit << " ";
}
rbegin() 和 rend() 是 C++ 中容器的成员函数,用于返回指向容器中最后一个元素和第一个元素前一个位置的逆向迭代器。
需要注意的是:
rbegin() 和 rend() 是 C++11 引入的函数,如果编译器不支持 C++11 特性,则可能无法使用这两个函数。在旧版本的 C++ 中,可以使用 reverse_iterator 类来手动创建逆向迭代器。
(6)插入迭代器 (Insert Iterator):
示例:
void test(){
std::vector<int> numbers1 = {1, 2, 3};
std::vector<int> numbers2 = {4, 5, 6};
std::vector<int> result;
std::copy(numbers1.begin(), numbers1.end(), std::back_inserter(result));
std::copy(numbers2.begin(), numbers2.end(), std::back_inserter(result));
for (const auto& num : result) {
std::cout << num << " ";
}
}
四:总结
以上示例展示了一些常用的迭代器类型以及它们在不同容器中的使用方法。这些示例说明了如何通过迭代器遍历容器元素、访问特定位置的元素、使用常量迭代器进行只读访问、使用反向迭代器进行逆序遍历等。
注意:
需要根据具体的需求和容器类型选择适当的迭代器类型,并使用相应的迭代器操作来操作容器的元素。
希望本文能够让大家能熟练掌握各种常用迭代器的内容和使用方法,记住多动手编程!
欢迎关注🔎点赞👍收藏⭐️留言📝