迭代器小结

在iterator头文件中,定义了3中迭代器:插入迭代器,iostream迭代器,以及反向迭代器。

先看插入迭代器。顾名思义,插入迭代器是往容器里添加元素的,分为三种:back_inserter、front_insert,以及insert,它们分别实现从头部、尾部以及任意地方插入。

通过一个简单的例子就能看出它们的区别


 

#include <iostream>
#include <list>
//算法库
#include <algorithm>
//特殊的迭代器
#include <iterator>
using namespace std;

int main()
{
	list<int> iList1;
	list<int> iList2(5,-1);
	list<int> iList3(5,-1);
	list<int> iList4(5,-1);

	for(int i = 0 ; i < 5;++i)
		iList1.push_back(i);
	//找到3
	list<int>::iterator iter = find(iList1.begin(),iList1.end(),3);
	//将3用30代替,并将结果顺序插入到iLsit2的头部
	replace_copy(iList1.begin(),iList1.end(),inserter(iList2,iList2.begin()),3,30);
	//显示结果
	for(list<int>::iterator it = iList2.begin();it != iList2.end();++it)
		cout<<*it<<"\t";
	cout<<endl;

	//插入到iLsit3的头部
	replace_copy(iList1.begin(),iList1.end(),front_inserter(iList3),3,30);
	//显示结果
	for(list<int>::iterator it = iList3.begin();it != iList3.end();++it)
		cout<<*it<<"\t";
	cout<<endl;

	//插入到iList的尾部
	replace_copy(iList1.begin(),iList1.end(),back_inserter(iList4),3,30);
	for(list<int>::iterator it = iList4.begin();it != iList4.end();++it)
		cout<<*it<<"\t";
	cout<<endl;
	return 0;
}


注意到,使用insert(iList2,iList2.begin())的结果输出的是0 1 2 30 4 -1...;而使用front_inserter的结果是4 30 2 1 0 -1...。

再看iostream迭代器,这类迭代器的作用,是将输入输出流与迭代器关联起来。

先看一个简单的例子:

	vector<int> vec;
	//将流迭代器与流绑定
	istream_iterator<int> in_iter(cin);
	//如果不初始化,则默认为超末端迭代器
	istream_iterator<int> eof;
	while(in_iter != eof)
		vec.push_back(*in_iter++);

	for(vector<int>::iterator it = vec.begin();it != vec.end();++it)
		cout<<*it<<endl;


 

是不是比我们传统的方法要简单一点呢?
现在先言归正传,看看流迭代器是如何定义并使用的。
流迭代器都是模版,在创建流迭代器时,必须将它与对应的流关联起来。
对于输入流迭代器,没有关联则意味着它表示的是迭代器的超末端位置。
对于输出流迭代器,则可以通过一个附加的参数来表明输出流之间的分隔符,这个参数必须是c风格的字符串:

	ostream_iterator<string> out_iter(cout,"s ");
	istream_iterator<string> in_iter(cin),eof;
	while(in_iter != eof)
	{
		*out_iter++ = *in_iter;
		in_iter++;

	}


 

这个c++primer原书上的程序是在循环中使用*out_iter++ = *in_iter++;但是这样做会有一个问题:就是最后输入的元素不能正确的输出。原因是因为*out_iter++ = *in_iter++是这样操作的:当你输入第一个字母a时,*out_iter = *in_iter会把它传给输出流迭代器,然后自增读入第二个字母b,这样依次类推,当你输入最后一个字母后,输入回车以后,虽然*out_iter = *in_iter可以正常执行,但是*in_iter++却没法执行了,所以这个赋值语句就没法执行,而经过修改以后的代码就避免了这个问题。这也算是鸡蛋里挑骨头吧!


现在再说说使用流迭代器的优点:算法是基于迭代器实现的,这意味着我们可以对流迭代器直接进行一些算法操作:

	istream_iterator<int> cin_it(cin);

	istream_iterator<int> eof;

	vector<int> ivec(cin_it,eof);
	sort(ivec.begin(),ivec.end());
	ostream_iterator<int> cout_it(cout," ");
	unique_copy(ivec.begin(),ivec.end(),cout_it);


最后我们看看反向迭代器。先看一个简单的例子:最后我们看看反向迭代器。先看一个简单的例子:最后我们看看反向迭代器。先看一个简单的例子:最后我们看看反向迭代器。

反向迭代器有什么用呢?其实当我们需要遍历容器,找出最后一个XX时,他就派上用场了:比如我们找出一句话中的最后一个单词:

	string line = "first, second, third, last";

	string::reverse_iterator rcomma = find(line.rbegin(), line.rend(), ' ');
	cout << string(line.rbegin(), rcomma) << endl; 


但是这会出现一个问题,打印结果不是last,而是tsal,就是把last也翻转了!为了或得正常的结果,需要将line.rbegin()和rcomma的顺序转换正常即可。其中line.rbegin肯定是转换为line.end(),而rcomma可以通过.base()转化:

	cout << string(rcomma.base(),line.end()) << endl;


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值