c++基础--为什么要使用迭代器?

目录

c++基础--为什么要使用迭代器?

-------------------------------------------------------

================================

c++基础--为什么要使用迭代器?

https://zhuanlan.zhihu.com/p/567985228

迭代器最大的好处是可以使容器和算法分离。

例如,有两个容器类:MyArray是某类型数组集合; MyLink是某类型链表集合。

它们都有显示、查询和排序等功能,

常规思维是每个容器类中有自己的显示,查询和排序等函数。

仔细分析可得出:不同容器中完成相同功能代码的思路大体是相同的,那么能不能把它们抽象出来,多个容器仅对应一个显示、一个查询、一个排序函数呢? 这是泛型思维发展的必然结果,于是迭代器思维就产生了。

C++ STL 迭代器详解

https://zhuanlan.zhihu.com/p/591795698

迭代器是一种抽象概念的实现,允许我们隔离算法数据结构无需太关心真实的数据结构实现

不同的算法对迭代器的要求也不同。

例如,

查找算法需要定义++运算符,以便迭代器能够遍历整个容器;它要求能够读取数据,但不要求能够写数据(它只是查看数据,而并不修改数据)。

而排序算法要求能够随机访问,以便能够交换两个不相邻的元素。如果iter 是一个迭代器,则可以通过定义+运算符来实现随机访问,这样就可以使用像 iter + 10这样的表达式了。另外,排序算法要求能够读写数据。

STL定义了5种迭代器,并根据所需的迭代器类型对算法进行了描述。这5种迭代器分别是输入迭代器、输出迭代器、正向迭代器、双向迭代器和随机访问迭代器。例如,find( )的原型与下面类似;

template<class InputIterator, class T>
InputIterator find (InputIterator first,InputIterator last,const T& value);

迭代器查找字符串中是否有特定字符

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv[]) {
        string myString{ "Bruce Sutherland" };
        string::iterator found = find(myString.begin(), myString.end(),'B');
        while (found != myString.end()) {
               cout << "Found:" << *found << endl;
               found = find(found + 1, myString.end(),'a');
        }
}

1.输入迭代器

输入迭代器(Input Iterator)。按顺序只读一次。完成的功能有:能进行构造和默认构造,能被复制或赋值,能进行相等性比较,能进行逐步向前移动,能进行读取值,需要输入迭代器的算法将不会修改容器中的值。输入迭代器重载主要操作符:

  • operator *
  • operator ==
  • operator ++()
  • operator ++(int)
  • operator !=
  • std::istream_iterator
    • istream_iterator() ==>缺省构造,创建一个流结束符迭代器
    • istream_iterator(istream& os)
#include <iostream>
#include <iterator>
using namespace std;
int main(){
    cout<<"请输入数据:";
    istream_iterator<int> input(cin);   //建立键盘输入流
    istream_iterator<int> stop;         //“哨兵”建立输入流结束迭代器
    while(1){
        cout<< *input <<endl;               //调用operator* ()
        input ++;                           //调用operator++ (int)
        if(input == stop){                     //调用operator==()
            break;
        }
    }
    return 0;
}

注意:由于迭代类型是整型数,只有在流中输入非整型数(空格),迭代器迭代到此位置时认为它不是整型数,这时才停止工作。

基于输入迭代器的任何算法都应当是单通行(single-pass)的,不依赖于前一次遍历时的迭代器值,也不依赖于本次遍历中前面的迭代器值。并且,输入迭代器是单向迭代器,可以递增,但不能倒退。

2.输出迭代器(Output Iterator)。

只写一次。完成的功能有:能进行构造或默认构造﹐能被复制或赋值,能进行相等性比较,能进行逐步前向移动,能进行写入值(* p=x,但不能读出)。

ostream_iterator

  • ostream_iterator(ostream& out):创建了流输出迭代器,用来迭代out输出流。
  • ostream_iterator(ostream& out,const char * delim):创建了流输出迭代器,用来向out输出流输出数据,输出的数据之间用delim字符串分隔。即每向out输出流输出一个数据后,就向out输出流输出一个分隔符delim。

3.前向迭代器(Forward Iterator)

使用输人迭代器和输出迭代器可以基本满足算法和容器的要求,但还是有一些算法需要同时具备两者的功能。例如replace算法就是一例。前向迭代器就是为满足这些需求而定义的。先看看replace算法(用新值代替旧值)的需求。

template<class ForwardTterator,class T>
void replace (ForwardIterator first,ForwardIterator last,const T& old_value,const T& new_value){
    for (;first!= last;++fist)
        if(* first==old_value)
            * first=new_value;
}

前向迭代器包含了输入和输出迭代器两者的所有功能,加上还可以多次解析一个迭代器指定的位置,因此可以对一个值进行多次读写。顾名思义,前向迭代器只能向前移动。但是STL本身并没有专为前向迭代器预定义的迭代器。这些特征使得多次通行算法成为可能。

4.双向迭代器(Bidirectional Iterator)

具有前向迭代器的全部功能,另外它还可以利用自减操作符operate--向后一次移动一个位置。例如双向链表容器中需要的就是双向迭代器。

例如,实现反转算法需要能够双向遍历容器。reverse 函数可以交换第一个元素和最后一个元素、将指向第一个元素的指针加1、将指向第二个元素的指针减1,并重复这种处理过程。双向迭代器具有正向迭代器的所有特性,同时支持两种(前缀和后缀)递减运算符。

5.随机访问迭代器(Random Access Iterator)

具有双向迭代器的所有功能,再加上一个指针所有的功能。包括使用操作符operator[]进行索引,加某个整数值到一个指针就可以向前或向后移动若干个位置,或者使用比较运算符在迭代器之间进行比较。

随机访问迭代器操作

迭代器层次结构

可能已经注意到,迭代器类型形成了一个层次结构。正向迭代器具有输入迭代器和输出迭代器的全部功能,同时还有自己的功能;双向迭代器具有正向迭代器的全部功能,同时还有自己的功能;随机访问迭代器具有正向迭代器的全部功能,同时还有自己的功能。如下表

根据特定迭代器类型编写的算法可以使用该种迭代器,也可以使用具有所需功能的任何其他迭代器。所以具有随机访问迭代器的容器可以使用为输入迭代器编写的算法。

为何需要这么多迭代器呢?目的是为了在编写算法尽可能使用要求最低的迭代器,并让它适用于容器的最大区间。这样,通过使用级别最低的输入迭代器,find()函数便可用于任何包含可读取值的容器。而sort()函数由于需要随机访问迭代器,所以只能用于支持这种迭代器的容器。因为过多的需求自然会降低它的效率,实际编程时应该选择正好合适的Iterator以期得到最高的效率。

编辑于 2022-12-20 16:01・IP 属地山西

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值