迭代器提供了顺序访问容器中每个元素的方法。迭代器可以使用"++"运算符获得下一个元素的迭代器,可以使用" * "运算符访问当前迭代器所指向的元素。如果元素类型是结构体或类,还可以使用“ ->” 运算符直接访问该元素的一个成员。
根据迭代器不同的特性,将迭代器分为5类:
迭代器类别 | 说明 |
---|---|
输入 | 从容器中读取元素。只能一次读入一个元素向前移动,只支持一遍算法,同一个输入迭代器不能两遍遍历一个序列 支持p++,++p,*p作为右值,p=p1,p==p1,p!=p1 |
输出 | 向容器中写入元素。只能一次一个元素向前移动,只支持一遍算法,统一输出迭代器不能两次遍历一个序列 支持p++,++p,*p作为左值,p=p1,p==p1,p!=p1 |
正向 | 组合输入迭代器和输出迭代器的功能,并保留在容器中的位置 |
双向 | 组合正向迭代器和逆向迭代器的功能,支持多遍算法 额外支持--p,p-- |
随机访问 | 组合双向迭代器的功,能与直接访问容器中任何元素的功能,即可向前向后跳过任意个元素 额外支持p+=i,p-=i,p+i(在p位加i位后的迭代器)p-i,p[i](返回p位元素偏离i位的元素引用)p<p1(如果迭代器p的位置在p1前,返回true,否则返回false) |
,
只有顺序容器和关联容器支持迭代器遍历下面列举了些例子说明各个容器迭代器的用法:
不同容器所对应的迭代器类型
array 随机访问迭代器
vector 随机访问迭代器
deque 随机访问迭代器
list 双向迭代器
set / multiset 双向迭代器
map / multimap 双向迭代器
forward_list 前向迭代器
unordered_map / unordered_multimap 前向迭代器
unordered_set / unordered_multiset 前向迭代器
stack 不支持迭代器
queue 不支持迭代器
1、vector,支持随机访问迭代器
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<char> charVector;
int x;
for(x=0; x<10; ++x)
{charVector.push_back(65 + x);}
int size = charVector.size();
for(x=0; x<size; ++x)
{
vector<char>::iterator start = charVector.begin();
charVector.erase(start);
vector<char>::iterator iter;实例化一个vector<char>类型的迭代器
for(iter = charVector.begin();iter != charVector.end(); iter++)遍历容器charVector
{
cout << *iter;//输出对应的值
}
cout << endl;
}
return0;
}
2、deque支持随机访问迭代器
#include <iostream>
#include <deque>
using name space std;
int main()
{
deque<char> charDeque;//声明一个char类型的队列
int x;
for(x=0; x<10; ++x)
charDeque.push_front(65 + x);//将元素从前面推入双端队列。
int size = charDeque.size();
for(x=0; x<size; ++x)
{
deque<char>::iterator start = charDeque.begin();
charDeque.erase(start);
deque<char>::iterator iter;
for(iter = charDeque.begin();iter != charDeque.end(); iter++)
{
cout << *iter;
}
cout << endl;
}
return0;
}
顺便介绍一下push_front()的用法
dequename.push_front(value)
Input:deque{5, 4, 3, 2, 1};
deque.push_front(6);
Output:6, 5, 4, 3, 2, 1
时间复杂度:O(1)
#include <deque>
#include <iostream>
using namespace std;
int main()
{
deque<int> mydeque{ 1, 2, 3, 4, 5 };
mydeque.push_front(6);
// deque becomes 6, 1, 2, 3, 4, 5
for (auto it = mydeque.begin(); it != mydeque.end(); ++it)
cout << ' ' << *it;
}
3、list双向
#include <iostream>
#include <list>
using namespace std;
int main()
{
int x;
list<char> charList;
for(x=0; x<10; ++x)
charList.push_front(65 + x);
cout << "Original list: ";
list<char>::iterator iter;
for(iter = charList.begin();iter != charList.end(); iter++)
{
cout << *iter;
//char ch = *iter;
//cout << ch;
}
cout << endl;
list<char>::iterator start = charList.begin();
charList.insert(++start, 5, 'X');
cout << "Resultant list: ";
for(iter = charList.begin();iter != charList.end(); iter++)
{
cout << *iter;
//char ch = *iter;
//cout << ch;
}
return0;
}
4.set 双向
#include <iostream>
#include <set>
using namespace std;
int main()
{
std::set<char> charSet;
charSet.insert('E');
charSet.insert('D');
charSet.insert('C');
charSet.insert('B');
charSet.insert('A');
cout << "Contents of set: " << endl;
set<char>::iterator iter;
for(iter = charSet.begin(); iter != charSet.end(); iter++)
cout << *iter << endl;
cout << :endl;
iter = charSet.find('D');
if(iter == charSet.end())
std::cout << "Element not found.";
else
std::cout << "Element found: " << *iter;
return0;
}
5.map双向
#include <iostream>
#include <map>
using namespace std;
typedef map<int,char> MYMAP;
int main()
{
MYMAP charMap1;
charMap1[1] = 'A';
charMap1[4] = 'D';
charMap1[2] = 'B';
charMap1[5] = 'E';
charMap1[3] = 'C';
cout << "Contents of first map: " << endl;
MYMAP::iterator iter;
for(iter = charMap1.begin();iter != charMap1.end(); iter++)
{
cout << (*iter).first << " --> ";
cout << (*iter).second << endl;
}
cout << endl;
MYMAP charMap2;
charMap2[1] = 'F';
charMap2[4] = 'I';
charMap2[2] = 'G';
charMap2[5] = 'J';
charMap2[3] = 'H';
cout << "Contents of second map: " << endl;
for(iter = charMap2.begin();iter != charMap2.end(); iter++)
{
(*iter).first << " --> ";
cout << (*iter).second << endl;
}
cout << endl;
if(charMap1 == charMap2)
cout << "map1 == map2";
elseif(charMap1 < charMap2)
cout << "map1 < map2";
elseif(charMap1 > charMap2)
cout << "map1 > map2";
return0;
}
迭代器按照定义方式分成以下四种。
1.正向迭代器,定义方法如下:
容器类名::iterator 迭代器名;
2.常量正向迭代器,定义方法如下:
容器类名::const_iterator 迭代器名;
3.反向迭代器,定义方法如下:
容器类名::reverse_iterator 迭代器名;
4.常量反向迭代器,定义方法如下:
容器类名::const_reverse_iterator 迭代器名;
通过迭代器可以读取它指向的元素,*迭代器名
就表示迭代器指向的元素。通过非常量迭代器还能修改其指向的元素。
迭代器都可以进行++
操作。反向迭代器和正向迭代器的区别在于:
- 对正向迭代器进行
++
操作时,迭代器会指向容器中的后一个元素; - 而对反向迭代器进行
++
操作时,迭代器会指向容器中的前一个元素。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v; //v是存放int类型变量的可变长数组,开始时没有元素
for (int n = 0; n<5; ++n)
v.push_back(n); //push_back成员函数在vector容器尾部添加一个元素
vector<int>::iterator i; //定义正向迭代器
for (i = v.begin(); i != v.end(); ++i) { //用迭代器遍历容器
cout << *i << " "; //*i 就是迭代器i指向的元素
*i *= 2; //每个元素变为原来的2倍
}
cout << endl;
//用反向迭代器遍历容器
for (vector<int>::reverse_iterator j = v.rbegin(); j != v.rend(); ++j)
//rbegin 成员函数返回指向容器中最后一个元素的迭代器,rend 成员函数返回指向容器中第一个元素前面的位置的迭代器
cout << *j << " ";
return 0;
}
写++i、++j相比于写i++、j++,程序的执行速度更快后置++
要多生成一个局部对象 tmp,因此执行速度比前置的慢。同理,迭代器是一个对象,STL 在重载迭代器的++
运算符时,后置形式也比前置形式慢。在次数很多的循环中,++i
和i++
可能就会造成运行时间上可观的差别了。因此,本教程在前面特别提到,对循环控制变量i,要养成写++i
、不写i++
的习惯。