C++ Primer 学习笔记_44_STL实践与分析(18)--再谈迭代器【下】
STL实践与分析
--再谈迭代器【下】
三、反向迭代器【续:习题】
//P355 习题11.19
int main()
{
vector<int> iVec;
for (vector<int>::size_type index = 0; index != 10; ++index)
{
iVec.push_back(index);
} for (vector<int>::reverse_iterator r_iter = iVec.rbegin();
r_iter != iVec.rend(); ++r_iter)
{
cout << *r_iter << endl;
}
}
//习题 11.20
int main()
{
vector<int> iVec;
for (vector<int>::size_type index = 0; index != 10; ++index)
{
iVec.push_back(index);
} for (vector<int>::iterator iter = iVec.end()-1;iter >= iVec.begin(); --iter)
{
cout << *iter << endl;
}
}
//习题 11.21
int main()
{
int ia[] = {0,1,2,3,4,5,6,0,7,8,9,0,10};
vector<int> iVec(ia,ia + sizeof(ia)/sizeof(*ia)); vector<int>::reverse_iterator r_iter = find(iVec.rbegin(),iVec.rend(),0);
if (r_iter != iVec.rend())
{
cout << "element after the last 0 : " << *(-- r_iter) << endl;
}
else
{
cout << "Not found!" << endl;
}
}
//习题11.22
int main()
{
int ia[] = {0,1,2,3,4,5,6,0,7,8};
vector<int> iVec(ia,ia + sizeof(ia)/sizeof(*ia)); list<int> iList; vector<int>::reverse_iterator rbeg = iVec.rbegin(),rend; for (int i = 0; i != 3; ++i)
++ rbeg; rend = rbeg;
for (int i = 0; i != 5; ++i)
++rend; copy(rbeg,rend,back_inserter(iList)); for (list<int>::iterator iter = iList.begin(); iter != iList.end(); ++iter)
{
cout << *iter << endl;
}
}
四、const迭代器
算法要求用于指定范围的两个迭代器必须具有全然一样的类型。比方我们曾将使用的find_first_of算法:
find_first_of(it, roster1.end(),roster2.begin(), roster2.end())
该函数调用的输入范围由it和调用roster1.end()返回的迭代器指定。算法要求用于指定范围的两个迭代器必须具有全然一样的类型。roster1.end()返回的迭代器依赖于roster1的类型。假设该容器是const对象,则返回的迭代器是const_iterator类型;否则,就是普通的iterator类型。在这个程序中,roster1不是 const对象,因而end返回的仅仅是一个普通的迭代器。
假设我们将it定义为const_iterator,那么find_first_of的调用将无法编译。用来指定范围的两个迭代器的类型不同样。it是 const_iterator类型的对象,而rotser1.end()返回的则是一个iterator对象。
五、五种迭代器
能够依据算法要求它的迭代器的提供什么类型的操作,对算法分类:
|
迭代器分类 |
|
|---|---|
|
输入迭代器 |
读,不能写:仅仅支持自增运算 |
|
输出迭代器 |
写,不能读:仅仅支持自增运算 |
|
前向迭代器 |
读和写:仅仅支持自增运算 |
|
双向迭代器 |
读和写:支持自增、自减运算 |
|
随机訪问迭代器 |
读和写:支持完整的迭代器算术运算 |
1、输入迭代器
可用于读取容器中的元素,可是不保证能够支持容器的写入操作。输入迭代器必须至少提供下列操作:
1)相等和不等操作符(==,!=),比較两个迭代器。
2)前置和后置的自增运算(++),使迭代器向前递进指向下一个元素。
3)用于读取元素的解引用操作符(*),此操作符仅仅能出如今赋值运算的右操作数上。
4)箭头操作符(->),这是(*it).member的同义语,也就是说,对迭代器进行解引用来获取其所关联的对象的成员。
输入迭代器仅仅能顺序使用;一旦输入迭代器自增了,就无法再用它检查之前的元素。要求在这个层次上提供支持的泛型算法包含find和 accumulate。标准库istream_iterator类型输入迭代器。
2、输出迭代器
能够视为与输入迭代器功能互补的迭代器;输入迭代器可用于向容器写入元素,但不保证能支持读取容器的内容。输入迭代器要求:
1)前置和后置的自增运算(++),使迭代器向前递进指向下一个元素。
2)解引用操作符(*),引操作符仅仅能出如今赋值运算的左操作数上。给解引用的输出迭代器赋值,将对该迭代器所指向的元素做写入操作。
输出迭代器能够要求每个迭代器的值必须正好写入一次。使用输出迭代器时,对于指定的迭代器值应该使用一次*运算,并且仅仅能用一次。输出迭代器一般用作算法的第三个实參,标记起始写入的位置。比如,copy算法使用一个输出迭代器作为它的第三个实參,将输入范围内的元素拷贝到输出迭代器指定的目标位置。标准库ostream_iterator类型输出迭代器
3、前向迭代器
用于读写指定的容器。这类迭代器仅仅会以一个方向遍历序列。前向迭代器支持输入迭代器和输出迭代器提供的全部操作,除此之外,还支持对同一个元素的多次读写。须要前向迭代器的泛型算法包含replace。
4、双向迭代器
从两个方向读写容器。出了提供前向迭代器的全部操作,还支持前置和后置的自减运算(--)。须要使用双向迭代器的泛型算法包含reverse。全部标准库容器提供的迭代器都至少达到双向迭代器的要求。
5、随机訪问迭代器
提供在常量时间内訪问容器任何位置的功能。不仅支持双向迭代器的全部功能,还支持以下的操作:
1)关系操作符<、<=、>和>=,比較两个迭代器的相对位置。
2)迭代器与整型数值n之间的加法和减法操作符+、+=、-和 -=,结果是迭代器在容器中向前(或退回)n个元素。
3)两个迭代器之间的减法操作符(--),得到两个迭代器间的距离。
4)下标操作符iter[n],这是*(iter+ n) 的同义词。
须要随机訪问迭代器的泛型算法包含sort算法。vector、deque和string迭代器是随机訪问迭代器,用作訪问内置数组元素的指针也是随机訪问迭代器。
除了输出迭代器,其它类别的迭代器形成了一个层次结构:须要低级类别迭代器的地方,可使用随意一种更高级的迭代器。
【总结】
map、set和 list类型提供双向迭代器,而string、vector和 deque容器上定义的迭代器都是随机訪问迭代器都是随机訪问迭代器,用作訪问内置数组元素的指针也是随机訪问迭代器。istream_iterator是输入迭代器,而ostream_iterator则是输出迭代器。
【关键概念:关联容器与算法】
虽然map和 set类型提供双向迭代器,但关联容器仅仅能使用算法的一个子集。问题在于:关联容器的键是const对象。因此,关联容器不能使用不论什么写序列元素的算法。仅仅能使用与关联容器绑在一起的迭代器来提供用于读操作的实參。
在处理算法时,最好将关联容器上的迭代器视为支持自减运算的输入迭代器,而不是完整的双向迭代器。
【重点理解】
C++标准为全部泛型和算术算法的每个迭代器形參指定了范围最小的迭代器种类。比如:find至少须要一个输入迭代器。replace函数至少须要一对前向迭代器。replace_copy函数的头两个迭代器必须至少是前向迭代器,第三个參数代表输出目标,必须至少是输出迭代器。
对于每个形參,迭代器必须保证最低功能。将支持更少功能的迭代器传递给函数是错误的;而传递更强功能的迭代器则没问题。
向算法传递无效的迭代器类别所引起的错误,无法保证会在编译时被捕获到。
//P358 习题11.26(d)
vector<int> iVec1,iVec2;
//...
//解释下列语句错误的原因,以及编译器是否能检測出这类错误?
sort(iVec1.begin(),iVec2.end());
C++ Primer 学习笔记_44_STL实践与分析(18)--再谈迭代器【下】的更多相关文章
- C++ Primer 学习笔记_43_STL实践与分析(17)--再谈迭代器【中】
STL实践与分析 --再谈迭代器[中] 二.iostream迭代[续] 3.ostream_iterator对象和ostream_iterator对象的使用 能够使用ostream_iterator对 ...
- C++ Primer 学习笔记_41_STL实践与分析(15)--先来看看算法【下一个】
STL实践与分析 --初窥算法[下] 一.写容器元素的算法 一些算法写入元素值.在使用这些算法写元素时一定要当心.必须.写入输入序列的元素 写入到输入序列的算法本质上是安全的--仅仅会写入与指定输入范 ...
- C++ Primer 学习笔记_29_STL实践与分析(3) --操作步骤集装箱(下一个)
STL实践与分析 --顺序容器的操作(下) 六.訪问元素 假设容器非空,那么容器类型的front和back成员将返回容器的第一个和最后一个元素的引用. [与begin和end的对照:] 1)begin ...
- C++ Primer 学习笔记_32_STL实践与分析(6) --再谈string类型(下)
STL实践与分析 --再谈string类型(下) 四.string类型的查找操作 string类型提供了6种查找函数,每种函数以不同形式的find命名.这些操作所有返回string::size_typ ...
- C++ Primer 学习笔记_35_STL实践与分析(9)--map种类(在)
STL实践与分析 --map类型(上) 引: map是键-值对的集合. map类型通常能够理解为关联数组:能够通过使用键作为下标来获取一个值,正如内置数组类型一样:而关联的本质在于元素的值与某个特定的 ...
- C++ Primer 学习笔记_46_STL实践与分析(20)--容器特有的算法
STL实践与分析 --容器特有的算法 与其它顺序容器所支持的操作相比,标准库为list容器定义了更精细的操作集合,使它不必仅仅依赖于泛型操作.当中非常大的一个原因就是list容器不是依照内存中的顺序进 ...
- C++ Primer 学习笔记_40_STL实践与分析(14)--概要、先来看看算法【上】
STL实践与分析 --概述.初窥算法[上] 标准库容器定义的操作很少.并没有给容器加入大量的功能函数.而是选择提供一组算法,这些算法大都不依赖特定的容器类型,是"泛型"的. ...
- C++ Primer 学习笔记_45_STL实践与分析(19)--建筑常规算法
STL实践与分析 --泛型算法的结构 引言: 正如全部的容器都建立在一致的设计模式上一样,算法也具有共同的设计基础. 算法最主要的性质是须要使用的迭代器种类.全部算法都指定了它的每一个迭代器形參可使用 ...
- C++ Primer 学习笔记_33_STL实践与分析(7) --容器适配器
STL实践与分析 --容器适配器 引: 除了顺序容器.标准库还提供了三种顺序容器适配器:queue,priority_queue和stack.适配器是标准库中的概念.包含容器适配器,迭代器适配器和函数 ...
随机推荐
- poj1189 简单dp
http://poj.org/problem?id=1189 Description 有一个三角形木板,竖直立放.上面钉着n(n+1)/2颗钉子,还有(n+1)个格子(当n=5时如图1).每颗钉子和周 ...
- Prime Path (poj 3126 bfs)
Language: Default Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11703 Ac ...
- 福州大学第十届校赛 & fzu 2128最长子串
思路: 对于每个子串,求出 母串中 所有该子串 的 开始和结束位置,保存在 mark数组中,求完所有子串后,对mark数组按 结束位置排序,然后 用后一个的结束位置 减去 前一个的 开始 位置 再 减 ...
- 数据字典的QUAN DEC类型与ABAP P型转换
转至:http://sap.iteye.com/blog/121584 今天突然想到的,肯定很多人知道,但是也肯定有一大堆人不知道. 转换公式 (n+1)/2 比如DEC定义为13位,其中3位小数 ...
- oracle 之数据字典屣履造门。
oracle 之数据字典屣履造门.(更新中) 今天是2013-06-20,哎,写这篇笔记的时候,我发现我是一个非常懒惰的人,这篇文章本该昨天就完成的,想起了钱鹤滩的<明日歌> ...
- poj 3623 Best Cow Line, Gold
题目不算难,但是不认真想的话很容易wa,我就是wa了多次才意识到自己想法存在的缺陷. 相同的时候往后找知道出现不相同时,只能判断出当前字符的优先顺序. 这个题目如果朴素的按照这种方法做的话复杂度其实是 ...
- javascript启示录英文单词生词
odd:奇怪的 represent:代表 primitive:原始的 trivial:平凡的 demonstrate:证明 keep this at the forefront of your min ...
- ajax+jsp实现三级联动下拉框
js文件sjld.js : $(document).ready( function(){ $.ajax({ url:"bindZ", type:"get", ...
- java OOP及相关基础知识汇总(转)
OOP 对象有三个要素 behavior 接口是怎样的,有什么方法/field可以用? state 调用方法的时候,对象会有什么反应? 只有通过调用方法才能改变一个对象的state identity ...
- GNU GPL介绍
怎样在程序中使用GNU许可证 不管使用哪种许可证,使用时须要在每一个程序的源文件里加入两个元素:一个版权声明和一个复制许可声明.说明该程序使用GNU许可证进行授权.另外在声明版权前应该说明 ...