30分钟掌握STL系列(四)

本文介绍了STL中的流和迭代器技术,包括如何利用I/O流读写数据,使用迭代器与流进行交互,以及如何运用不同类型的插入迭代器(如front_inserter和back_inserter)高效地操作容器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                                                                                                        30分钟掌握STL系列(四)

这一节中学习相关的STL技术。

流和迭代器

本书的很多例子程序使用I/O流语句来读写数据。例如:

int value;
cout << "Enter value: ";
cin >> value;
cout << "You entered " << value << endl;
对于迭代器,有另一种方法使用流和标准函数。理解的要点是将输入/输出流作为容
器看待。因此,任何接受迭代器参数的算法都可以和流一起工作。
#i nclude <iostream.h>
#i nclude <stdlib.h> // Need random(), srandom()
#i nclude <time.h> // Need time()
#i nclude <algorithm> // Need sort(), copy()
#i nclude <vector> // Need vector

using namespace std;

void Display(vector<int>& v, const char* s);

int main()
{
// Seed the random number generator
srandom( time(NULL) );

// Construct vector and fill with random integer values
vector<int> collection(10);
for (int i = 0; i < 10; i++)
collection[i] = random() % 10000;;

// Display, sort, and redisplay
Display(collection, "Before sorting");
sort(collection.begin(), collection.end());
Display(collection, "After sorting");
return 0;
}

// Display label s and contents of integer vector v
void Display(vector<int>& v, const char* s)
{
cout << endl << s << endl;
copy(v.begin(), v.end(),
ostream_iterator<int>(cout, "\t"));
cout << endl;
}
函数Display()显示了如何使用一个输出流迭代器。下面的语句将容器中的值传输到
cout输出流对象中:

copy(v.begin(), v.end(),
ostream_iterator<int>(cout, "\t"));
第三个参数实例化了ostream_iterator<int>类型,并将它作为copy()函数的输出目
标迭代器对象。“\t”字符串是作为分隔符。运行结果:

$ g++ outstrm.cpp
$ ./a.out
Before sorting
677 722 686 238 9*** 397 251 118 11 312
After sorting
11 118 238 251 312 397 677 686 722 9***
这是STL神奇的一面『确实神奇』。为定义输出流迭代器,STL提供了模板类ostream_ite
rator
。这个类的构造函数有两个参数:一个ostream对象和一个string值。因此可以象下
面一样简单地创建一个迭代器对象:

ostream_iterator<int>(cout, "\n")
该迭代起可以和任何接受一个输出迭代器的函数一起使用。


插入迭代器


插入迭代器用于将值插入到容器中。它们也叫做适配器,因为它们将容器适配或转化
为一个迭代器,并用于copy()这样的算法中。例如,一个程序定义了一个链表和一个
矢量容器:
list<double> dList;
vector<double> dVector;
通过使用front_inserter迭代器对象,可以只用单个copy()语句就完成将矢量中的对
象插入到链表前端的操作:
copy(dVector.begin(), dVector.end(), front_inserter(dList));
三种插入迭代器如下:

· 普通插入器 将对象插入到容器任何对象的前面。

· Front inserters 将对象插入到数据集的前面——例如,链表表头。

· Back inserters 将对象插入到集合的尾部——例如,矢量的尾部,导致
矢量容器扩展。

使用插入迭代器可能导致容器中的其他对象移动位置,因而使得现存的迭代器非法。
例如,将一个对象插入到矢量容器将导致其他值移动位置以腾出空间。一般来说,插
入到象链表这样的结构中更为有效,因为它们不会导致其他对象移动。

//program: insert.cpp
#include <iostream.h>
#include <algorithm>
#include <list>
using namespace std;
int iArray[5] = { 1, 2, 3, 4, 5 };
void Display(list<int>& v, const char* s);
int main()
{
list<int> iList;
// Copy iArray backwards into iList
copy(iArray, iArray + 5, front_inserter(iList));
Display(iList, "Before find and copy");
// Locate value 3 in iList
list<int>::iterator p =
find(iList.begin(), iList.end(), 3);
// Copy first two iArray values to iList ahead of p
copy(iArray, iArray + 2, inserter(iList, p));
Display(iList, "After find and copy");
return 0;
}
void Display(list<int>& a, const char* s)
{
cout << s << endl;
copy(a.begin(), a.end(),
ostream_iterator<int>(cout, " "));
cout << endl;
}
运行结果如下:

$ g++ insert.cpp
$ ./a.out
Before find and copy
5 4 3 2 1
After find and copy
5 4 1 2 3 2 1
可以将front_inserter替换为back_inserter******。
如果用find()去查找在列表中不存在的值,例如99。由于这时将p设置为past-the-end
值。最后的copy()函数将iArray的值附加到链表的后部。

混合迭代器函数
在涉及到容器和算法的操作中,还有两个迭代器函数非常有用:
· advance() 按指定的数目增减迭代器。
· distance() 返回到达一个迭代器所需(递增)操作的数目。
例如:
list<int> iList;
list<int>::iterator p =
find(iList.begin(), iList.end(), 2);
cout << "before: p == " << *p << endl;
advance(p, 2); // same as p = p + 2;
cout << "after : p == " << *p << endl;
advance()函数接受两个参数。第二个参数是向前推进的数目。对于前推迭代器,该
值必须为正,而对于双向迭代器和随机访问迭代器,该值可以为负。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值