STL之迭代器

STL是C++中重要部分之一(面向对象、STL、模板等),其中三个基本的STL组件包括: 1. 迭代器。迭代器之于容器相当于指针之于数组,提供了访问容器对象的方法,事实上C++中的指针也是一种迭代器,但是要注意迭代器不仅仅是指针,不一定具有地址值。 2. 容器。容器是一种模板类,例如list、vector、deque等,一般由迭代器访问容器中的数据。 3. 算法。STL中数据结构和算法是分离的,各种函数在广义容器中(包括链表、数组、string对象、容器)完全通用,只要支持相应的迭代器即可。 1.头文件: STL头文件一般不使用.h扩展,其中主要使用的头文件和对应容器类如下: #include Container Class deque list map, multimap queue, priority_queue set, multiset stack vector string ***<***>::iterator 各种算法函数 STL均使用标准命名空间using namespace std。 2.迭代器: 迭代器有五种类型,这五种类型是一种继承关系,具体如下: Input iterators:提供对数据的只读访问,前向推进。输入迭代器可以使用==和!=来测试是否相等;使用*来访问数据;使用++操作符前向推进。例如find函数需要保证输入迭代器。 Output iterators:提供对数据的只写访问,前向推进。输出迭代器缺省只写,由于该迭代器无法读取对象,因此不会在任何搜索和其他算法中使用它。 Forward iterators:提供读写访问,前向推进。例如replace函数需要保证前向迭代器。 Bidirectional iterators:提供读写访问,前向或后向推进。例如reverse函数需要保证双向迭代器。 Random access iterators:提供读写访问,随机移动(非const的指针也是随机迭代器)。STL中的排序和搜索函数使用随机访问迭代器,随机访问迭代器可以使用关系操作符做比较。 除此之外,还包括一些特殊的迭代器: 指针迭代器:一个指针也是一种迭代器。 常量迭代器:对于只读变量,为了防止错误赋值,可以使用常量迭代器const_iterator,该迭代器指向的对象不允许改变。注意:const ***<***>::iterator的含义是该迭代器成为常量,不可指向其他数据,与常量迭代器的含义是不一样的。 3.流迭代器 将输入输出(例如标准输入输出流cin/cout或者文件流等)作为容器看待,因此接受迭代器参数的算法都可以和流一起工作。 STL定义模板类ostream_iterator作为输出流迭代器,其构造函数有两个参数,包括一个ostream对象和一个string值(作为间隔符),因此可以象下面一样创建一个迭代器: ostream_iterator out(cout, “/t”) //定义cout迭代器,可以和任何一个接受输出迭代器的函数一起使用,如copy copy(....., ......, out); ofstream out(“text.txt”); ostream_iterator obegin(out, “/n”); //定义文件流输出迭代器 ---------------------------------------- STL定义模板类istream_iterator作为输入流迭代器,可指定读取的来源,并应该和结束迭代器比较。具体如下: istream_iterator intreader(cin); //定义cin流迭代器,输出结束用ctrl+Z+回车 isteam_iterator eof; //空的流迭代器表示结束 copy(istream_iterator (cin), istream_iterator (), 输出迭代器); //定义无变量名的cin流迭代器 ifstream in(“text.txt”); istream_iterator ibegin(in); istream_iterator iend; //定义文件流输入迭代器 还有一些具体应用如下: //利用流迭代器填充vector { ifstream in("test.txt"); istream_iterator ibegin(in); istream_iterator iend; vector vec(ibegin, iend); //貌似会有问题,类型不匹配 copy(vec.begin(), vec.end(), ostream_iterator (cout, "/n")); } //利用输入流填充vector { vector vec; copy(istream_iterator (cin), istream_iterator (), back_inserter(vec)); sort(vec.begin(), vec.end()); copy(vec.begin(), vec.end(), ostream_iterator (cout,"/n")); } //利用流迭代器保存vector内容到文件 { ifstream in("test.txt"); istream_iterator ibegin(in); istream_iterator iend; vector vec(ibegin, iend); ofstream out("testcopy.txt"); copy(vec.begin(), vec.end(), ostream_iterator (out, "/n")); } 注意:上面用输入流迭代器来初始化vector后,不可再用这个输入流迭代器,因为随着数据的读取,迭代器已经到达输入流或者文件流的末尾了。 4.插入迭代器: int arr[] = {1, 2, 3, 4, 5}; vector vi; copy(arr, arr + 5; vi.begin()); 该语句不会执行,因为没有为vi分配存储空间。此时使用插入迭代器可以将值插入到容器中,自动为vi扩展存储空间,主要包括三种插入迭代器。 普通插入器:将对象插入到容器任何对象的前面。该迭代器使用容器的insert操作符替代赋值运算符,第一个参数是容器本身,第二个参数是容器迭代器指定插入位置。 Front inserters:将对象插入到数据集的前面,例如链表表头。该迭代器使用push_front操作替代赋值运算符,参数是容器本身。注意如vector没有push_front的操作,所以不能使用front_inserter迭代器。 Back inserters:将对象插入到数据集的尾部,例如vector的尾部,导致vector容器扩展。该迭代器调用容器的push_back操作替代赋值运算符,参数是容器本身。 注意:使用插入迭代器可能导致容器中的其他对象移动位置,因此现有的迭代器变成非法,需要重新赋值(list除外,不受影响)。 int arr[] = {1, 2, 3, 4, 5}; list vi; copy(arr, arr + 5; front_inserter(vi)); //最终结果按序是5 4 3 2 1,因为每次调用push_front将一个数据插入到vi的前面。 list ::iterator p = find(vi.begin(), vi.end(), 2); copy(arr, arr + 2, inserter(vi, p)); //最终结果是5 4 3 1 2 2 1,因为调用insert一次性将所有数据插入到p前。 5.混合迭代器函数: 下面两个迭代器函数非常有用: advance(iterator, int):按照指定的数目增减迭代器,iterator改变。第一个参数是迭代器,第二个参数是增减的数目(前向迭代器该数必须为正,双向或者随机迭代器该数可以为负)。 distance(iterator, iterator):返回到达一个迭代器所需递增操作的数目,即两个迭代器相差的距离。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值