1 头文件

所有容器有含有其各自的迭代器型别(iterator types),所以当你使用一般的容器迭代器时,并不需要含入专门的头文件。不过有几种特别的迭代器,例如逆向迭代器,被定义于<iterator>中。

2 迭代器类型

迭代器共分为五种,分别为: Input iterator、Output iterator、Forward iterator、Bidirectional iterator、Random access iterator。

2.1 Input(输入)迭代器

只能一次一个向前读取元素,按此顺序一个个传回元素值。表2.1列出了Input迭代器的各种操作行为。Input迭代器只能读取元素一次,如果你复制Input迭代器,并使原Input迭代器与新产生的副本都向前读取,可能会遍历到不同的值。纯粹Input迭代器的一个典型例子就是“从标准输入装置(通常为键盘)读取数据”的迭代器。

表达式                      功能表述

*iter                  读取实际元素

iter->member           读取实际元素的成员(如果有的话)

++iter                 向前步进(传回新位置)

iter++                 向前步进(传回旧位置)

iter1 == iter2         判断两个迭代器是否相同

iter1 != iter2         判断两个迭代器是否不相等

TYPE(iter)             复制迭代器(copy 构造函数)                                                                  

2.2 Output(输出)迭代器

Output迭代器和Input迭代器相反,其作用是将元素值一个个写入。表2.2列出Output迭代器的有效操作。operator*只有在赋值语句的左手边才有效。Output迭代器无需比较(comparison)操作。你无法检验Output迭代器是否有效,或“写入动作”是否成功。你唯一可以做的就是写入、写入、再写入。

表达式                  功能表述

*iter = value      将元素写入到迭代器所指位置

++iter             向前步进(传回新位置)

iter++             向前步进(传回旧位置)

TYPE(iter)         复制迭代器(copy 构造函数)                                                                  

2.3 Forward(前向)迭代器

Forward迭代器是Input迭代器与Output迭代器的结合,具有Input迭代器的全部功能和Output迭代器的大部分功能。表2.3总结了Forward迭代器的所有操作。Forward迭代器能多次指向同一群集中的同一元素,并能多次处理同一元素。

表达式                 功能表述

*iter               存取实际元素

iter->member        存取实际元素的成员

++iter              向前步进(传回新位置)

iter++              向前步进(传回旧位置)

iter1 == iter2      判断两个迭代器是否相同

iter1 != iter2      判断两个迭代器是否不相等

TYPE()              产生迭代器(default构造函数)

TYPE(iter)          复制迭代器(copy构造函数)

iter1 == iter2      复制                                                              

2.4 Bidirectional(双向)迭代器

Bidirectional(双向)迭代器在Forward迭代器的基础上增加了回头遍历的能力。换言之,它支持递减操作符,用以一步一步的后退操作。

2.5 Random Access(随机存取)迭代器

Random Access迭代器在Bidirectional迭代器的基础上再增加随机存取能力。因此它必须提供“迭代器算数运算”(和一般指针“指针算术运算”相当)。也就是说,它能加减某个偏移量、能处理距离(differences)问题,并运用诸如<和>的相互关系操作符进行比较。以下对象和型别支持Random Access迭代器:

  • 可随机存取的容器(vector, deque)

  • strings(字符串,string,wstring)

  • 一般array(指针)

3 迭代器相关辅助函数

3.1 advance()令迭代器前进

3.2 distance() 处理迭代器之间的距离

3.3 iter_swap()交换两个迭代器所指内容

4  迭代器配接器

4.1 Reverse(逆向迭代器)

逆向迭代器重新定义递增运算和递减运算,使其行为正好倒置。成员函数rbegin()和rend()各传回一个Reverse迭代器,和begin()和end()类似,共同定义一个半开区间。用正向迭代器可以直接构造一个逆向迭代器,但是构造之后会出现“错位”现象。原因在逆向迭代器要保证半开区间不会越界,可调用逆向迭代器的base()函数,保证转换值的正确性(迭代器移了一位)。

4.2 Insert(安插型)迭代器

Insert迭代器,也称为inserters,用来将“赋值新值”操作转换为“安插新值”操作。通过这种迭代器,算法可以执行安插(insert)行为而非覆盖(overwrite)行为。所有Insert迭代器都隶属于Output迭代器类型。所以它只提供赋值(assign)新值的能力。表4.2.1列出Insert迭代器的所有操作函数。

表达式            功能表述

*iter           无实际操作(传回iter)

iter = value    安插value

++iter          无实际操作(传回iter)

iter++          无实际操作(传回iter)

                                                             

C++标准程序库提供三种Insert迭代器:back inserters, front inserters, general inserters。它们的区别在于插入位置。事实上它们各自调用所属容器中不同的成员函数。所以Insert迭代器初始化时要清楚知道自己所属的容器是哪一种。表4.2.2列出Insert迭代器的种类。

     名称                     Class                 其所调用的函数             生成函数

Back   inserter     back_inserter_iterator         push_back(value)        back_inserter(cont)

Front inserter      front_insert_iterator          push_front(value)       front_inserter(cont)

General inserter    insert_iterator                insert(pos, value)       inserter(cont, pos)

4.3 Stream(流)迭代器

Stream迭代器是一种迭代器配接器,通过它,你可以把stream当成算法的原点和终点。更明确的说,一个istream迭代器可以用来从input stream中读元素,而一个ostream迭代器可以用来对output stream写入元素。

Stream迭代器的一种特殊形式是所谓的stream缓冲区迭代器,用来对stream缓冲区进行直接读取和写入操作。

Ostream迭代器

ostream迭代器 可以被赋予的值写入output stream中。下表列出ostream迭代器的各项操作

 

         算式                               功能表述

ostream_iterator<T>(ostream)          为ostream产生一个ostream迭代器

ostream_iterator<T>(ostream, delim)   为ostream产生一个ostream迭代器,各元素间以delim为分隔符(请注意,delim的型别是const char*)

*iter                                 无实际操作(传回iter)

iter = value                          将value写到ostream,像这样:ostream<<value。其后再输出一个delim(分隔符;如有定义的话)

++iter                                无实际操作(传回iter)

iter++                                 无实际操作(传回iter)

Istream迭代器

istream迭代器是ostream迭代器的拍档,用来从input stream读取元素。透过istream迭代器,算法可以从stream中直接读取数据。istream迭代器的各项操作。

        算式                                功能表述

istream_iterator<T>()                 产生一个end-of-stream迭代器

istream_iterator<T>(istream)          为istream产生的一个迭代器(可能立即去读第一个元素)

*iter                                 传回先前读取的值(如果构造函数并未立刻读取第一个元素值,则本式执行读取任务)

iter->member                          传回先前读取的元素的成员(如果有的话)

++iter                                读取下一个元素,并传回其位置

iter++                                读取下一个元素,并传回迭代器指向前一个元素

iter1 == iter2                        检查iter1和iter2是否相等

iter1 != iter2                        检查iter1和iter2是否不相等

5.下面列举了些例子说明各个容器的用法:

1、vector
#include <iostream>
#include <vector> int main()
{
std::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)
{
std::vector<char>::iterator start =
charVector.begin();
charVector.erase(start);
std::vector<char>::iterator iter;
for (iter = charVector.begin();
iter != charVector.end(); iter++)
{
std::cout << *iter;
}
std::cout << std::endl;
} return 0;
}
2、deque
#include <iostream>
#include <deque> int main()
{
std::deque<char> charDeque;
int x;
for (x=0; x<10; ++x)
charDeque.push_front(65 + x); int size = charDeque.size();
for (x=0; x<size; ++x)
{
std::deque<char>::iterator start =
charDeque.begin();
charDeque.erase(start);
std::deque<char>::iterator iter;
for (iter = charDeque.begin();
iter != charDeque.end(); iter++)
{
std::cout << *iter;
}
std::cout << std::endl;
} return 0;
}
3、list
#include <iostream>
#include <list> int main()
{
// Create and populate the list.
int x;
std::list<char> charList;
for (x=0; x<10; ++x)
charList.push_front(65 + x); // Display contents of list.
std::cout << "Original list: ";
std::list<char>::iterator iter;
for (iter = charList.begin();
iter != charList.end(); iter++)
{
std::cout << *iter;
//char ch = *iter;
//std::cout << ch;
}
std::cout << std::endl; // Insert five Xs into the list.
std::list<char>::iterator start = charList.begin();
charList.insert(++start, 5, 'X'); // Display the result.
std::cout << "Resultant list: ";
for (iter = charList.begin();
iter != charList.end(); iter++)
{
std::cout << *iter;
//char ch = *iter;
//std::cout << ch;
} return 0;
}
4、set
#include <iostream>
#include <set> int main()
{
// Create the set object.
std::set<char> charSet; // Populate the set with values.
charSet.insert('E');
charSet.insert('D');
charSet.insert('C');
charSet.insert('B');
charSet.insert('A'); // Display the contents of the set.
std::cout << "Contents of set: " << std::endl;
std::set<char>::iterator iter;
for (iter = charSet.begin(); iter != charSet.end(); iter++)
std::cout << *iter << std::endl;
std::cout << std::endl; // Find the D.
iter = charSet.find('D');
if (iter == charSet.end())
std::cout << "Element not found.";
else
std::cout << "Element found: " << *iter; return 0;
}
5、multiset
#include <iostream>
#include <set> int main()
{
// Create the first set object.
std::multiset<char> charMultiset1; // Populate the multiset with values.
charMultiset1.insert('E');
charMultiset1.insert('D');
charMultiset1.insert('C');
charMultiset1.insert('B');
charMultiset1.insert('A');
charMultiset1.insert('B');
charMultiset1.insert('D'); // Display the contents of the first multiset.
std::cout << "Contents of first multiset: " << std::endl;
std::multiset<char>::iterator iter;
for (iter = charMultiset1.begin();
iter != charMultiset1.end(); iter++)
std::cout << *iter << std::endl;
std::cout << std::endl; // Create the second multiset object.
std::multiset<char> charMultiset2; // Populate the multiset with values.
charMultiset2.insert('J');
charMultiset2.insert('I');
charMultiset2.insert('H');
charMultiset2.insert('G');
charMultiset2.insert('F');
charMultiset2.insert('G');
charMultiset2.insert('I'); // Display the contents of the second multiset.
std::cout << "Contents of second multiset: "
<< std::endl;
for (iter = charMultiset2.begin();
iter != charMultiset2.end(); iter++)
std::cout << *iter << std::endl;
std::cout << std::endl; // Compare the sets.
if (charMultiset1 == charMultiset2)
std::cout << "set1 == set2";
else if (charMultiset1 < charMultiset2)
std::cout << "set1 < set2";
else if (charMultiset1 > charMultiset2)
std::cout << "set1 > set2"; return 0;
}
6、map
#include <iostream>
#include <map> typedef std::map<int, char> MYMAP; int main()
{
// Create the first map object.
MYMAP charMap1; // Populate the first map with values.
charMap1[1] = 'A';
charMap1[4] = 'D';
charMap1[2] = 'B';
charMap1[5] = 'E';
charMap1[3] = 'C'; // Display the contents of the first map.
std::cout << "Contents of first map: " << std::endl;
MYMAP::iterator iter;
for (iter = charMap1.begin();
iter != charMap1.end(); iter++)
{
std::cout << (*iter).first << " --> ";
std::cout << (*iter).second << std::endl;
}
std::cout << std::endl; // Create the second map object.
MYMAP charMap2; // Populate the first map with values.
charMap2[1] = 'F';
charMap2[4] = 'I';
charMap2[2] = 'G';
charMap2[5] = 'J';
charMap2[3] = 'H'; // Display the contents of the second map.
std::cout << "Contents of second map: " << std::endl;
for (iter = charMap2.begin();
iter != charMap2.end(); iter++)
{
std::cout << (*iter).first << " --> ";
std::cout << (*iter).second << std::endl;
}
std::cout << std::endl; // Compare the maps.
if (charMap1 == charMap2)
std::cout << "map1 == map2";
else if (charMap1 < charMap2)
std::cout << "map1 < map2";
else if (charMap1 > charMap2)
std::cout << "map1 > map2"; return 0;
}
7、multimap
#include <iostream>
#include <map> typedef std::multimap<int, char> MYMAP; int main()
{
// Create the first multimap object.
MYMAP charMultimap; // Populate the multimap with values.
charMultimap.insert(MYMAP::value_type(1,'A'));
charMultimap.insert(MYMAP::value_type(4,'C'));
charMultimap.insert(MYMAP::value_type(2,'B'));
charMultimap.insert(MYMAP::value_type(7,'E'));
charMultimap.insert(MYMAP::value_type(5,'D'));
charMultimap.insert(MYMAP::value_type(3,'B'));
charMultimap.insert(MYMAP::value_type(6,'D')); // Display the contents of the first multimap.
std::cout << "Contents of first multimap: " << std::endl;
MYMAP::iterator iter;
for (iter = charMultimap.begin();
iter != charMultimap.end(); iter++)
{
std::cout << (*iter).first << " --> ";
std::cout << (*iter).second << std::endl;
}
std::cout << std::endl; // Create the second multimap object.
MYMAP charMultimap2; // Populate the second multimap with values.
charMultimap2.insert(MYMAP::value_type(1,'C'));
charMultimap2.insert(MYMAP::value_type(4,'F'));
charMultimap2.insert(MYMAP::value_type(2,'D'));
charMultimap2.insert(MYMAP::value_type(7,'E'));
charMultimap2.insert(MYMAP::value_type(5,'F'));
charMultimap2.insert(MYMAP::value_type(3,'E'));
charMultimap2.insert(MYMAP::value_type(6,'G')); // Display the contents of the second multimap.
std::cout << "Contents of second multimap: " << std::endl;
for (iter = charMultimap2.begin();
iter != charMultimap2.end(); iter++)
{
std::cout << (*iter).first << " --> ";
std::cout << (*iter).second << std::endl;
}
std::cout << std::endl; // Compare the multimaps.
if (charMultimap == charMultimap2)
std::cout << "multimap1 == multimap2";
else if (charMultimap < charMultimap2)
std::cout << "multimap1 < multimap2";
else if (charMultimap > charMultimap2)
std::cout << "multimap1 > multimap2"; return 0;
}
8、stack
#include <iostream>
#include <list>
#include <stack> int main()
{
std::stack<int, std::list<int> > intStack; int x;
std::cout << "Values pushed onto stack:"
<< std::endl;
for (x=1; x<11; ++x)
{
intStack.push(x*100);
std::cout << x*100 << std::endl;
} std::cout << "Values popped from stack:"
<< std::endl;
int size = intStack.size();
for (x=0; x<size; ++x)
{
std::cout << intStack.top() << std::endl;
intStack.pop();
} return 0;
}
9、queue
#include <iostream>
#include <list>
#include <queue> int main()
{
std::queue<int, std::list<int> > intQueue; int x;
std::cout << "Values pushed onto queue:"
<< std::endl;
for (x=1; x<11; ++x)
{
intQueue.push(x*100);
std::cout << x*100 << std::endl;
} std::cout << "Values removed from queue:"
<< std::endl;
int size = intQueue.size();
for (x=0; x<size; ++x)
{
std::cout << intQueue.front() << std::endl;
intQueue.pop();
} return 0;
}
10、priority_queue
#include <iostream>
#include <list>
#include <queue> int main()
{
std::priority_queue<int, std::vector<int>,std::greater<int> > intPQueue;
int x;
intPQueue.push(400);
intPQueue.push(100);
intPQueue.push(500);
intPQueue.push(300);
intPQueue.push(200); std::cout << "Values removed from priority queue:"
<< std::endl;
int size = intPQueue.size();
for (x=0; x<size; ++x)
{
std::cout << intPQueue.top() << std::endl;
intPQueue.pop();
} return 0;
}

STL之迭代器(iterator)的更多相关文章

  1. STL 笔记(四) 迭代器 iterator

    stl 中迭代器能够理解为面向对象版本号的广义指针,提供了对容器中的对象的訪问方法,能够遍历容器全部元素.也能够訪问随意元素.stl 迭代器有下面五种: Input iterators   仅仅读,输 ...

  2. STL的迭代器和类型萃取

    今天就可以把STL库中迭代器的实现,和类型萃取好好整理一下了 迭代器的设计思维是STL的关键所在,在STL的实际运用和泛型思维,迭代器都扮演着十分重要的角色,STL力求把数据容器和算法的概念分开来,于 ...

  3. C++迭代器 iterator【转】

    1. 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型.(1) 每种容器类型都定义了自己的迭代器类型,如vector:vector<int>::iterator iter ...

  4. 带你深入理解STL之迭代器和Traits技法

    在开始讲迭代器之前,先列举几个例子,由浅入深的来理解一下为什么要设计迭代器. //对于int类的求和函数 int sum(int *a , int n) { int sum = 0 ; for (in ...

  5. STL中实现 iterator trail 的编程技巧

    STL中实现 iterator trail 的编程技巧 <泛型编程和 STL>笔记及思考. 这篇文章主要记录在 STL 中迭代器设计过程中出现的编程技巧,围绕的 STL 主题为 (迭代器特 ...

  6. C++迭代器 iterator

    1. 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型.(1) 每种容器类型都定义了自己的迭代器类型,如vector:vector<int>::iterator iter ...

  7. 设计模式C++描述----20.迭代器(Iterator)模式

    一. 举例说明 我们知道,在 STL 里提供 Iterator 来遍历 Vector 或者 List 数据结构. Iterator 模式也正是用来解决对一个聚合对象的遍历问题,将对聚合的遍历封装到一个 ...

  8. C++ 标准模板库(STL)——迭代器(iterators)的用法及理解

    C++ STL中迭代器(iterators)用于遍历对象集合的元素.由于容器大小随着插入删除等操作动态改变,无法像静态数组那样获取数组长度然后遍历容器里的所有元素:这时就需要迭代器,每次从容器内第一个 ...

  9. 用struts2标签如何从数据库获取数据并在查询页面显示。最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变量。

    最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变 ...

随机推荐

  1. JAVA课程设计——一个简单的教务人事管理系统

    大三上学期期末总结,没错,上学期,写在下学期新学期开始,哈哈哈. 上学期学习了面向对象程序设计,课程设计的题目使用JAVA语言完成一个简单的教务人事管理系统,能够实现访问数据库的登录验证,分别按部门和 ...

  2. 网络爬虫之html2md

    前言 上周利用java爬取的网络文章,一直未能利用java实现html转化md,整整一周时间才得以解决. 虽然本人的博客文章数量不多,但是绝不齿于手动转换,毕竟手动转换浪费时间,把那些时间用来做些别的 ...

  3. [EOJ629] 两开花

    Description 给定一棵以 \(1\) 为根 \(n\) 个节点的树. 定义 \(f(k)\) :从树上等概率随机选出 \(k\) 个节点,这 \(k\) 个点的虚树大小的期望. 一个点 \( ...

  4. 使用NetworkX模块绘制深度神经网络(DNN)结构图

      本文将展示如何利用Python中的NetworkX模块来绘制深度神经网络(DNN)结构图.   在文章Keras入门(一)搭建深度神经网络(DNN)解决多分类问题中,我们创建的DNN结构图如下: ...

  5. 使用sublime text3编写vuejs项目需要安装的一些插件

    最近使用webstorm开发vuejs项目的时候经常出现卡顿的现象,感觉还是sublime text3比较轻巧便捷,但是使用sublime text3需要安装一些插件- 1. 让vue文件高亮: 安装 ...

  6. C# ThreadPool类(线程池)

    CLR线程池并不会在CLR初始化时立即建立线程,而是在应用程序要创建线程来运行任务时,线程池才初始化一个线程.线程池初始化时是没有线程的,线程池里的线程的初始化与其他线程一样,但是在完成任务以后,该线 ...

  7. Linux日志 系统日志及分析

    Linux系统拥有非常灵活和强大的日志功能,可以保存几乎所有的操作记录,并可以从中检索出我们需要的信息. 大部分Linux发行版默认的日志守护进程为 syslog,位于 /etc/syslog 或 / ...

  8. Java高并发 -- 并发扩展

    Java高并发 -- 并发扩展 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 死锁 死锁是指两个或两个以上的事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象, ...

  9. angular 拼接html 事件无效

    主要是要引用$compile方法

  10. angular input 为file on-change 无效

    l转自:https://blog.csdn.net/klo220/article/details/53331229 侵删 出现这个问题是因为input的type是file,这时如果用ng-change ...