STL 中的迭代器有以下几种:输入迭代器、输出迭代器、正向迭代器、双向迭代器、随机访问迭代器。
1. 输入迭代器:一次只能读取一个元素,只能向前移动,支持:++、==、!=、(只读)
2. 输出迭代器:一次只能写一个元素,只能向前移动,支持:++、==、!=、(只写)
3. 正向迭代器:一次可以读写元素,只能向前移动,支持++、==、!=、(读写)
4. 双向迭代器:一次可以读写元素,能够双向移动,支持++、–、==、!=、(读写)
5. 随机迭代器:一次可以读写一个元素,支持正向、反向、任意位置移动。支持:++、–、==、!=、*(读写)、+=、+ -、-=、[]等
#include <iostream>
#include <vector>
#include <deque>
#include <forward_list>
#include <list>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
using namespace std;
#include <iostream>
#include <vector>
#include <deque>
#include <forward_list>
#include <list>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
using namespace std;
#include <iostream> #include <vector> #include <deque> #include <forward_list> #include <list> #include <set> #include <unordered_set> #include <map> #include <unordered_map> using namespace std;
1. 容器支持的迭代器
算法使用的迭代器种类是不同的,比如,有些算法要求迭代器类型必须是随机访问迭代器,那么,你的容器提供的是双向迭代器,就用不了这种算法。
void test01()
{
// 1. vector 提供的迭代器是随机访问迭代器
vector<int>::iterator it1;
it1 += 5;
// 2. deque 提供的迭代器是随机访问迭代器
deque<int>::iterator it2;
it2 += 5;
// 3. forward_list 提供的是正向迭代器
forward_list<int>::iterator it3;
// it3 += 5; // 语法报错
it3++;
// it3--; // 语法报错
// 4. list 提供的是双向迭代器
list<int>::iterator it4;
// it4 += 5; // 语法报错
it4++;
it4--;
// 5. set 提供的是双向迭代器
set<int>::const_iterator it5;
// it5 += 5; // 语法错误
it5++;
it5--;
// 6. unordered_set 提供的是双向迭代器
unordered_set<int>::iterator it6;
// it6 += 5; // 语法错误
it6++;
it6--;
// 7. map 容器提供的是双向迭代器
map<int, int>::iterator it7;
// it7 += 5; // 语法错误
it7++;
it7--;
// 8. unordered_map 提供的是双向迭代器
unordered_map<int, int>::iterator it8;
// it8+=5;
it8++;
it8--;
}
void test01()
{
// 1. vector 提供的迭代器是随机访问迭代器
vector<int>::iterator it1;
it1 += 5;
// 2. deque 提供的迭代器是随机访问迭代器
deque<int>::iterator it2;
it2 += 5;
// 3. forward_list 提供的是正向迭代器
forward_list<int>::iterator it3;
// it3 += 5; // 语法报错
it3++;
// it3--; // 语法报错
// 4. list 提供的是双向迭代器
list<int>::iterator it4;
// it4 += 5; // 语法报错
it4++;
it4--;
// 5. set 提供的是双向迭代器
set<int>::const_iterator it5;
// it5 += 5; // 语法错误
it5++;
it5--;
// 6. unordered_set 提供的是双向迭代器
unordered_set<int>::iterator it6;
// it6 += 5; // 语法错误
it6++;
it6--;
// 7. map 容器提供的是双向迭代器
map<int, int>::iterator it7;
// it7 += 5; // 语法错误
it7++;
it7--;
// 8. unordered_map 提供的是双向迭代器
unordered_map<int, int>::iterator it8;
// it8+=5;
it8++;
it8--;
}
void test01() { // 1. vector 提供的迭代器是随机访问迭代器 vector<int>::iterator it1; it1 += 5; // 2. deque 提供的迭代器是随机访问迭代器 deque<int>::iterator it2; it2 += 5; // 3. forward_list 提供的是正向迭代器 forward_list<int>::iterator it3; // it3 += 5; // 语法报错 it3++; // it3--; // 语法报错 // 4. list 提供的是双向迭代器 list<int>::iterator it4; // it4 += 5; // 语法报错 it4++; it4--; // 5. set 提供的是双向迭代器 set<int>::const_iterator it5; // it5 += 5; // 语法错误 it5++; it5--; // 6. unordered_set 提供的是双向迭代器 unordered_set<int>::iterator it6; // it6 += 5; // 语法错误 it6++; it6--; // 7. map 容器提供的是双向迭代器 map<int, int>::iterator it7; // it7 += 5; // 语法错误 it7++; it7--; // 8. unordered_map 提供的是双向迭代器 unordered_map<int, int>::iterator it8; // it8+=5; it8++; it8--; }
2. 迭代器辅助函数
- advance 函数:向前或者向后移动某个容器的迭代器到某个位置
- distance 函数:用于计算两个迭代器之间相差元素的个数
- iter_swap 函数:交换两个迭代器指向的元素的值
void test02()
{
// 1. advance 函数:向前或者向后移动某个容器的迭代器到某个位置
vector<int> v = { 10, 20, 30, 40, 50 };
auto it1 = v.begin() + 3;
list<int> l = { 10, 20, 30, 40, 50 };
auto it2 = l.begin();
//it2++;
//it2++;
//it2++;
advance(it2, 3);
// 2. distance 函数:用于计算两个迭代器之间相差元素的个数
// 参数为两个迭代器区间,一般这两个迭代器都指向同一个容器
distance(v.begin(), it1);
// 3. iter_swap 函数:交换两个迭代器指向的元素的值
// iter_swap(v.begin(), it1);
iter_swap(v.begin(), it2);
for (auto val : v) cout << val << " ";
cout << endl;
}
template<class T>
ostream& operator<<(ostream& os, const vector<T>& vec)
{
for (auto v : vec) cout << v << " ";
return os;
}
template<class T>
ostream& operator<<(ostream& os, const deque<T>& vec)
{
for (auto v : vec) cout << v << " ";
return os;
}
void test02()
{
// 1. advance 函数:向前或者向后移动某个容器的迭代器到某个位置
vector<int> v = { 10, 20, 30, 40, 50 };
auto it1 = v.begin() + 3;
list<int> l = { 10, 20, 30, 40, 50 };
auto it2 = l.begin();
//it2++;
//it2++;
//it2++;
advance(it2, 3);
// 2. distance 函数:用于计算两个迭代器之间相差元素的个数
// 参数为两个迭代器区间,一般这两个迭代器都指向同一个容器
distance(v.begin(), it1);
// 3. iter_swap 函数:交换两个迭代器指向的元素的值
// iter_swap(v.begin(), it1);
iter_swap(v.begin(), it2);
for (auto val : v) cout << val << " ";
cout << endl;
}
template<class T>
ostream& operator<<(ostream& os, const vector<T>& vec)
{
for (auto v : vec) cout << v << " ";
return os;
}
template<class T>
ostream& operator<<(ostream& os, const deque<T>& vec)
{
for (auto v : vec) cout << v << " ";
return os;
}
void test02() { // 1. advance 函数:向前或者向后移动某个容器的迭代器到某个位置 vector<int> v = { 10, 20, 30, 40, 50 }; auto it1 = v.begin() + 3; list<int> l = { 10, 20, 30, 40, 50 }; auto it2 = l.begin(); //it2++; //it2++; //it2++; advance(it2, 3); // 2. distance 函数:用于计算两个迭代器之间相差元素的个数 // 参数为两个迭代器区间,一般这两个迭代器都指向同一个容器 distance(v.begin(), it1); // 3. iter_swap 函数:交换两个迭代器指向的元素的值 // iter_swap(v.begin(), it1); iter_swap(v.begin(), it2); for (auto val : v) cout << val << " "; cout << endl; } template<class T> ostream& operator<<(ostream& os, const vector<T>& vec) { for (auto v : vec) cout << v << " "; return os; } template<class T> ostream& operator<<(ostream& os, const deque<T>& vec) { for (auto v : vec) cout << v << " "; return os; }
3. 迭代器适配器
3.1 插入型迭代器
- 尾插型迭代器 back_inserter 支持的容器有 vector、deque、list 等有 push_back 函数的容器
- 头插迭代器 front_inserter 支持的容器有 deque、list、forward_list 等有 push_front 函数的容器
- 指定位置插入的迭代器 inserter 支持的容器有 vector、list 等有 insert 函数的容器
void test03()
{
vector<int> v = { 10, 20, 30 };
// 1. 尾插型迭代器(vector、deque、list)
// back_inserter 函数可以获得某个容器的尾部插入迭代器
back_insert_iterator<vector<int>> it1 = back_inserter(v);
// it1 叫做尾部插入迭代器,对该迭代器的赋值操作,将会导致元素插入到容器尾部
it1 = 100;
*it1 = 200;
cout << v << endl;
// 注意:使用尾插迭代器,容器必须有 push_back 函数。
// 2. 头插迭代器(deque、list、forward_list)
deque<int> d = { 10, 20, 30 };
// 使用 front_inserter 获得某个容器的头部插入迭代器
front_insert_iterator<deque<int>> it2 = front_inserter(d);
// 对该迭代器的赋值操作,将会导致元素添加到容器的头部
it2 = 666;
*it2 = 888;
cout << d << endl;
// 3. 指定位置插入的迭代器
// 使用 inserter 函数获得该迭代器
vector<int> v2 = { 10, 20, 30 };
insert_iterator<vector<int>> it3 = inserter(v2, v2.begin() + 1);
it3 = 111;
*it3 = 222;
cout << v2 << endl;
}
void test03()
{
vector<int> v = { 10, 20, 30 };
// 1. 尾插型迭代器(vector、deque、list)
// back_inserter 函数可以获得某个容器的尾部插入迭代器
back_insert_iterator<vector<int>> it1 = back_inserter(v);
// it1 叫做尾部插入迭代器,对该迭代器的赋值操作,将会导致元素插入到容器尾部
it1 = 100;
*it1 = 200;
cout << v << endl;
// 注意:使用尾插迭代器,容器必须有 push_back 函数。
// 2. 头插迭代器(deque、list、forward_list)
deque<int> d = { 10, 20, 30 };
// 使用 front_inserter 获得某个容器的头部插入迭代器
front_insert_iterator<deque<int>> it2 = front_inserter(d);
// 对该迭代器的赋值操作,将会导致元素添加到容器的头部
it2 = 666;
*it2 = 888;
cout << d << endl;
// 3. 指定位置插入的迭代器
// 使用 inserter 函数获得该迭代器
vector<int> v2 = { 10, 20, 30 };
insert_iterator<vector<int>> it3 = inserter(v2, v2.begin() + 1);
it3 = 111;
*it3 = 222;
cout << v2 << endl;
}
void test03() { vector<int> v = { 10, 20, 30 }; // 1. 尾插型迭代器(vector、deque、list) // back_inserter 函数可以获得某个容器的尾部插入迭代器 back_insert_iterator<vector<int>> it1 = back_inserter(v); // it1 叫做尾部插入迭代器,对该迭代器的赋值操作,将会导致元素插入到容器尾部 it1 = 100; *it1 = 200; cout << v << endl; // 注意:使用尾插迭代器,容器必须有 push_back 函数。 // 2. 头插迭代器(deque、list、forward_list) deque<int> d = { 10, 20, 30 }; // 使用 front_inserter 获得某个容器的头部插入迭代器 front_insert_iterator<deque<int>> it2 = front_inserter(d); // 对该迭代器的赋值操作,将会导致元素添加到容器的头部 it2 = 666; *it2 = 888; cout << d << endl; // 3. 指定位置插入的迭代器 // 使用 inserter 函数获得该迭代器 vector<int> v2 = { 10, 20, 30 }; insert_iterator<vector<int>> it3 = inserter(v2, v2.begin() + 1); it3 = 111; *it3 = 222; cout << v2 << endl; }
3.2 反向迭代器
reverse_iterator 适配器主要用于获得容器的反向迭代器。
void test04()
{
vector<int> v = { 10, 20, 30 };
// reverse_iterator<容器迭代器类型>
// 指定位置:v.end 对于反向迭代器而言就是 30, 对于正向迭代器 30 后面的位置
reverse_iterator<vector<int>::iterator> it(v.end());
cout << *it << endl;
cout << *(++it) << endl;
cout << *(++it) << endl;
}
void test04()
{
vector<int> v = { 10, 20, 30 };
// reverse_iterator<容器迭代器类型>
// 指定位置:v.end 对于反向迭代器而言就是 30, 对于正向迭代器 30 后面的位置
reverse_iterator<vector<int>::iterator> it(v.end());
cout << *it << endl;
cout << *(++it) << endl;
cout << *(++it) << endl;
}
void test04() { vector<int> v = { 10, 20, 30 }; // reverse_iterator<容器迭代器类型> // 指定位置:v.end 对于反向迭代器而言就是 30, 对于正向迭代器 30 后面的位置 reverse_iterator<vector<int>::iterator> it(v.end()); cout << *it << endl; cout << *(++it) << endl; cout << *(++it) << endl; }
3.3 流式迭代器
输出流迭代器:
void test05()
{
// 1. 输出流迭代器的使用
ostream_iterator<int> it1(cout, "|");
// 对 it1 这个输出流对象的赋值操作,都会导致将其输出到屏幕
it1 = 100;
*it1 = 200;
// 2. 使用输出流迭代器将容器元素打印到屏幕上
vector<int> v = { 10, 20, 30, 40, 50 };
// copy(开始,结束,目标开始); 将前两个参数标定的区间赋值到第三个参数指定的容器中
ostream_iterator<int> it2(cout, "|");
copy(v.begin(), v.end(), it2);
/*
for(; first != last; ++first)
{
*dst = *first;
}
*/
}
void test05()
{
// 1. 输出流迭代器的使用
ostream_iterator<int> it1(cout, "|");
// 对 it1 这个输出流对象的赋值操作,都会导致将其输出到屏幕
it1 = 100;
*it1 = 200;
// 2. 使用输出流迭代器将容器元素打印到屏幕上
vector<int> v = { 10, 20, 30, 40, 50 };
// copy(开始,结束,目标开始); 将前两个参数标定的区间赋值到第三个参数指定的容器中
ostream_iterator<int> it2(cout, "|");
copy(v.begin(), v.end(), it2);
/*
for(; first != last; ++first)
{
*dst = *first;
}
*/
}
void test05() { // 1. 输出流迭代器的使用 ostream_iterator<int> it1(cout, "|"); // 对 it1 这个输出流对象的赋值操作,都会导致将其输出到屏幕 it1 = 100; *it1 = 200; // 2. 使用输出流迭代器将容器元素打印到屏幕上 vector<int> v = { 10, 20, 30, 40, 50 }; // copy(开始,结束,目标开始); 将前两个参数标定的区间赋值到第三个参数指定的容器中 ostream_iterator<int> it2(cout, "|"); copy(v.begin(), v.end(), it2); /* for(; first != last; ++first) { *dst = *first; } */ }
输入流迭代器:
void test06()
{
// 1. 输出入流迭代器使用
// 输入需要标定开始输入、结束输入,所以需要创建两个对象
// istream_iterator<int> first(cin); // 将 cin 对象转换为迭代器对象
// istream_iterator<int> last; // 输入流结束迭代器对象
// *first 表示要从迭代器获取数据,如果没有数据会等待数据。
// 指向键盘输入的第一个数据
//int v1 = *first;
//cout << v1 << endl;
// 表示获取下一个输入
//int v2 = *(++first);
//cout << v2 << endl;
// 2. 通过输入流迭代器给容器赋值
// 结束输入:ctrl + z
vector<int> v2;
v2.resize(10); // 将大小变成10,并初始化10个对象
istream_iterator<int> my_first(cin);
istream_iterator<int> my_end;
// copy 内部是赋值操作,目前 v2 中不存在元素,也没有空间,此时是不能赋值。
copy(my_first, my_end, v2.begin());
cout << v2 << endl;
}
void test06()
{
// 1. 输出入流迭代器使用
// 输入需要标定开始输入、结束输入,所以需要创建两个对象
// istream_iterator<int> first(cin); // 将 cin 对象转换为迭代器对象
// istream_iterator<int> last; // 输入流结束迭代器对象
// *first 表示要从迭代器获取数据,如果没有数据会等待数据。
// 指向键盘输入的第一个数据
//int v1 = *first;
//cout << v1 << endl;
// 表示获取下一个输入
//int v2 = *(++first);
//cout << v2 << endl;
// 2. 通过输入流迭代器给容器赋值
// 结束输入:ctrl + z
vector<int> v2;
v2.resize(10); // 将大小变成10,并初始化10个对象
istream_iterator<int> my_first(cin);
istream_iterator<int> my_end;
// copy 内部是赋值操作,目前 v2 中不存在元素,也没有空间,此时是不能赋值。
copy(my_first, my_end, v2.begin());
cout << v2 << endl;
}
void test06() { // 1. 输出入流迭代器使用 // 输入需要标定开始输入、结束输入,所以需要创建两个对象 // istream_iterator<int> first(cin); // 将 cin 对象转换为迭代器对象 // istream_iterator<int> last; // 输入流结束迭代器对象 // *first 表示要从迭代器获取数据,如果没有数据会等待数据。 // 指向键盘输入的第一个数据 //int v1 = *first; //cout << v1 << endl; // 表示获取下一个输入 //int v2 = *(++first); //cout << v2 << endl; // 2. 通过输入流迭代器给容器赋值 // 结束输入:ctrl + z vector<int> v2; v2.resize(10); // 将大小变成10,并初始化10个对象 istream_iterator<int> my_first(cin); istream_iterator<int> my_end; // copy 内部是赋值操作,目前 v2 中不存在元素,也没有空间,此时是不能赋值。 copy(my_first, my_end, v2.begin()); cout << v2 << endl; }