文章目录
大vvvvvv
迭代器的使用(初阶)--持续更新
按需求抓重点。收藏起来
最后一次更新与2月28日
说明
本文注重讲解常用的方法,偏方容易把我搞的云里雾里。
原创文章,未经允许禁止转载
迭代器的定义
迭代器(Iterator)用来访问和检查 STL
容器中元素的对象,它的行为模式和指针类似,但是它封装了一些有效性检查,并且提供了统一的访问格式。类似的概念在其他很多高级语言中都存在,如
Python 的 iter 函数,C# 的 IEnumerator。(来自IO Wiki)
简单的说,就是一种工具,用来遍历STL容器用的,有的像vector可以像数组那样for循环加个‘i’去遍历,但是set等其他容器只能用迭代器去遍历。
迭代器的简单代码使用(原始代码)
这个代码可以简单看一下迭代器的使用思路。详情请按需跳转(省略了万能头文件和主函数)
//遍历vector
vector<int> v(10);
for(int i = 0;i<v.size();i++)
v[i]=i; //对其赋值
for (int i = 0; i < v.size(); i++)
cout << v[i] << ' '; // 使用下标遍历元素
cout<<endl;
for (vector<int>::iterator it= v.begin(); it!= v.end(); it++)
cout << *it <<' '; // 使用迭代器遍历元素
cout<<endl;
//简写 vector<int>::iterator it= v.begin()可以写成 auto it = v.begin();详情请查看简写迭代器
运行结果
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
//遍历 set
set<int> s;
for(int i = 0;i<10;i++)
s.insert(i); //对其赋值
for(set<int>::iterator it = s.begin();it!=s.end();it++)
cout<<*it<<' '; // 使用迭代器遍历元素
cout<<endl;
运行结果
0 1 2 3 4 5 6 7 8 9
其他容器遍历请看相应的STL的讲解
迭代器的创造
迭代器有5种,但归根结底,就是一种,我们可以直接把他当做一种数据类型去记忆如果你要声明一个迭代器,你可以像声明一个int 或者 double 类型一样去声明它,但是注意的是,在iterator这个类型前面还有加一个迭代器的种类。如下代码。
vector<int>::iterator itv //我要创造一个vector类型的迭代器,叫 itv
set<int> :: iterator its //我要创造一个set类型的迭代器,叫its
等等,可以把“::”理解为的,“我要声明一个XX类型的iterator叫XX”
迭代器的运算
由原始代码可以知道,迭代器实质是申请一个指针,也就是说原始代码的it是一个指针,通过某种规则不断移动。但是它的运算规则并不是普通指针哪有。
1.赋值“=”运算符,竟然是指针,那么你的赋值就只能是地址了,所以我们经常使用begin(),和end()。看代码
vector<int> v(10);
for(int i = 0;i<v.size();i++)
v[i]=i; //对其赋值
vector<int> :: iterator it = v.begin()+1; //第二个元素
cout<<*it<<endl; //
it = v.end() - 1; //最后一个元素。注意不是v.end().
cout<<*it<<endl;
运行结果
1
9
2.自增自减运算符“++”,“–”,这两个运算符是遍历整个容器常用的运算符,意味着指针像容器前面移动一位或者两位。看代码
vector<int> v(10);
for(int i = 0;i<v.size();i++)
v[i]=i; //对其赋值
vector<int> :: iterator it = v.begin()+1;
it = ++it; //如果写成it++结果不一样,因为它遵循自增自减运算,先赋值还是后赋值
cout<<*it<<endl;
--it;
cout<<*it<<endl;
运行结果
2
1
3.加减运算符 既然有自增自减,那么就可以加减。也就是不是每次指针就是加一。看代码。
vector<int> v(10);
for(int i = 0;i<v.size();i++)
v[i]=i; //对其赋值
vector<int> :: iterator it = v.begin();
it = it + 1; //相当于v.begin()+1,也就是v[1]的位置
cout<<*it<<endl;
it = it + 5; //相当于v.begin()+6(之前加了1),也就是v[6]
cout<<*it<<endl;
it = it - 6; //来到v.begin()
cout<<*it<<endl;
运行结果
1
6
0
“取值运算符‘*’”:‘*’运算符我个人感觉叫取值更好理解,因为it是指针,指的是一个房间,那么我要拿到房间里的东西,就是取,就用 星号运算符因此我喜欢叫他取值运算符,学过指针的都知道他的作用,不做过多讲解
简写迭代器
写在前面,这个简写,我个人不太鼓励初学者去写,因为容易搞混或者搞不明白迭代器的原理,如果你熟练了,在写不迟。
auto是在在C++11后可以使用。但比赛选手要注意下面的提示
大部分选手都喜欢使用 auto 来代替繁琐的迭代器声明。但是需要注意的是,auto 需要 C++11 版本,而 NOI 系列比赛在评测时使用的是 C++98。
NOI 官网上最新的 NOI 系列活动标准竞赛环境 明确了 C++ 编译器版本为 G++ 4.8.4,且编译指令为 g++ test.cpp -o test,并没有携带 --std=c++11 参数,而 gcc 从 6.0 版本起才将默认版本修改为 C++14。
因此,在比赛时使用 auto 时需要注意 CE 爆零的风险。(来自OI Wiki)
具体适用看代码
vector<int> v(10);
for(int i = 0;i<v.size();i++)
v[i]=i; //对其赋值
vector<int> :: iterator it = v.begin();
auto ita = v.begin(); //这里面的auto可以取代vector<int> :: iterator。
cout<<*it<<' '<<*ita<<endl;
运行结果
0 0
auto的用法可不只这么点,背后的原理可以自行查找,因篇幅原因不做讲解。
持续更新