本文概述
迭代器就像用于访问容器元素的指针一样。
重要事项
- 迭代器用于从一个元素遍历到另一个元素, 这个过程称为遍历容器。
- 迭代器的主要优点是为所有容器类型提供通用接口。
- 迭代器使算法独立于所用容器的类型。
- 迭代器提供了一种遍历容器元素的通用方法。
句法
<ContainerType> :: iterator;
<ContainerType> :: const_iterator;
在迭代器上执行的操作
- 运算符(*):“ *”运算符返回迭代器指向的当前位置的元素。
- 运算符(++):“ ++”运算符将迭代器加1。因此, 迭代器指向容器的下一个元素。
- 运算符(==)和运算符(!=):这两个运算符都确定两个迭代器是否指向相同的位置。
- 运算符(=):’=’运算符分配迭代器。
差异黑白迭代器和指针
迭代器可以是智能指针, 它可以迭代复杂的数据结构。容器提供其迭代器类型。因此, 可以说迭代器具有不同容器类型的公共接口。
容器类提供了两个基本的成员函数, 它们允许迭代或遍历容器的元素:
- begin():begin()函数返回一个迭代器, 该迭代器指向容器的第一个元素。
- end():end()函数返回指向容器的last-the-last元素的迭代器。
让我们看一个简单的例子:
#include <iostream>
#include<iterator>
#include<vector>
using namespace std;
int main()
{
std::vector<int> v{1, 2, 3, 4, 5};
vector<int>::iterator itr;
for(itr=v.begin();itr!=v.end();itr++)
{
std::cout << *itr <<" ";
}
return 0;
}
输出:
1 2 3 4 5
迭代器类别
迭代器可以通过以下方式进行分类:
- 输入迭代器
- 输出迭代器
- 正向迭代器
- 双向迭代器
- 随机访问迭代器
输入迭代器:输入迭代器是用于从容器访问元素的迭代器, 但它不会修改容器的值。
用于输入迭代器的运算符为:
- 增量运算符(++)
- 等于运算符(==)
- 不等于运算符(!=)
- 解引用运算符(*)
输出迭代器:输出迭代器是用于修改容器值的迭代器, 但不会从容器中读取值。因此, 可以说输出迭代器是只写迭代器。
用于输出迭代器的运算符为:
- 增量运算符(++)
- 赋值运算符(=)
转发迭代器:转发迭代器是用于读取和写入容器的迭代器。这是一个多遍迭代器。
用于正向迭代器的运算符为:
- 增量运算符(++)
- 赋值运算符(=)
- 等于运算符(=)
- 不等于运算符(!=)
双向迭代器:双向迭代器是一种支持正向迭代器的所有功能的迭代器, 另外还增加了一个功能, 即递减运算符(-)。我们可以通过减少迭代器来向后移动。
用于双向迭代器的运算符为:
- 增量运算符(++)
- 赋值运算符(=)
- 等于运算符(=)
- 不等于运算符(!=)
- 减量运算符(-)
随机访问迭代器:随机访问迭代器是一个迭代器, 可在任意位置对元素进行随机访问。它具有双向迭代器的所有功能, 另外还增加了一个功能, 即指针添加和指针减法以提供对元素的随机访问。
迭代器的提供者
迭代器类别 | 提供者 |
---|---|
Input iterator | istream |
Output iterator | ostream |
转发迭代器 | |
双向迭代器 | 列出, 设置, 多组, 地图, 多图 |
随机访问迭代器 | 向量, 双端队列, 阵列 |
迭代器及其特征
迭代器 | 访问方式 | 运动方向 | I / O能力 |
---|---|---|---|
Input | Linear | 仅向前 | Read-only |
Output | Linear | 仅向前 | Write-only |
Forward | Linear | Forward only | Read/Write |
Bidirectional | Linear | 向前向后 | Read/Write |
Random | Random | 向前向后 | Read/Write |
迭代器的缺点
- 如果我们想同时从一种数据结构转移到另一种数据结构, 则迭代器将无法工作。
- 如果我们要更新正在迭代的结构, 则迭代器由于其存储位置的方式而不允许我们这样做。
- 如果我们要在处理列表时回退, 则在这种情况下, 迭代器将无法工作。
迭代器的优点
以下是迭代器的优点:
- 易于编程:使用迭代器比使用下标operator []访问容器的元素更方便。如果我们使用下标operator []访问元素, 则需要跟踪运行时添加的元素数量, 但是在迭代器的情况下不会发生这种情况。
让我们看一个简单的例子:
#include <iostream>
#include<vector>
#include<iterator>
using namespace std;
int main()
{
vector<int> v{1, 2, 3, 4, 5};
vector<int>::iterator itr;
for(int i=0;i<5;i++) // Traversal without using an iterator.
{
cout<<v[i]<<" ";
}
cout<<'\n';
for(itr=v.begin();itr!=v.end();itr++) // Traversal by using an iterator.
{
cout<<*itr<<" ";
}
v.push_back(10);
cout<<'\n';
for(int i=0;i<6;i++)
{
cout<<v[i]<<" ";
}
cout<<'\n';
for(itr=v.begin();itr!=v.end();itr++)
{
cout<<*itr<<" ";
}
return 0;
}
输出:
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5 10
1 2 3 4 5 10
在上面的示例中, 我们观察到, 如果不使用迭代器遍历向量的元素, 则需要跟踪容器中添加的元素数量。
- 代码可重用性:如果我们使用迭代器, 则可以重用代码。在上面的示例中, 如果我们用列表替换vector, 则下标operator []将无法访问元素, 因为列表不支持随机访问。但是, 我们使用迭代器来访问元素, 然后我们也可以访问列表元素。
- 动态处理:C ++迭代器提供了动态添加或删除数据的功能。
让我们看一个简单的例子:
#include <iostream>
#include<vector>
#include<iterator>
using namespace std;
int main()
{
vector<int> v{1, 2, 3, 4, 5}; // vector declaration
vector<int>::iterator itr;
v.insert(v.begin()+1, 10);
for(itr=v.begin();itr!=v.end();itr++)
{
cout<<*itr<<" ";
}
return 0;
}
输出:
1 10 2 3 4 5
在上面的示例中, 我们使用insert()函数在第二个位置插入了一个新元素, 所有其他元素都移位了一个。
差异黑白随机访问迭代器和其他迭代器
随机访问迭代器与其他迭代器之间最重要的区别是, 随机访问迭代器需要’1’步骤来访问元素, 而其他迭代器则需要’n’步骤。
评论前必须登录!
注册