
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
迭代器是许多软件编程开发程序员在学习和应用过程中都需要熟练掌握的一个编程工具,而本文我们就通过案例分析来简单了解一下,迭代器的概念与应用分析。
一、什么是迭代器?我们为什么要使用迭代器?
什么是迭代器?当我初学Python的时候,我将迭代器理解为一种能够放在“forxxxin...”的“...”位置的东西;后来随着学习的深入,我了解到迭代器就是一种实现了迭代器协议的对象;学习C++时,我了解到迭代器是一种行为和指针类似的对象...
事实上,迭代器是一个伴随着迭代器模式(IteratorPattern)而生的抽象概念,其目的是分离并统一不同的数据结构访问其中数据的方式,从而使得各种需要访问数据结构的函数,对于不同的数据结构可以保持相同的接口。
在很多讨论Python迭代器的书籍与文章中,我看到这样两种观点:1.迭代器是为了节约数据结构所产生的内存;2.遍历迭代器效率更高。
这两点论断都是很不准确的:先,除了某些不定义在数据结构上的迭代器(如文件句柄,itertools模块的count、cycle等无限迭代器等),其他迭代器都定义在某种数据结构上,所以不存在节约内存的优势;其次,由于迭代器是一种高度泛化的实现,其需要在每一次迭代器移动时都做一些额外工作(如Python需要不断检测迭代器是否耗尽,并进行异常监测;C++的deque容器需要对其在堆上用于存储的多段不连续内存进行衔接等),故遍历迭代器的效率一定低于或几乎接近于直接遍历容器,而不太可能高于直接遍历原容器。
综上所述,迭代器存在的意义,不是为了空间换时间,也不是为了时间换空间,而是一种适配器(Adapter)。迭代器的存在,使得我们可以使用同样的for语句去遍历各种容器,或是像C++的algorithm模块所示的那样,使用同样的接口去处理各种容器。
这些容器可以是一个连续内存的数组或列表,或是一个多段连续内存的deque,甚至是一个完全不连续内存的链表或是哈希表等等,我们完全不需要关注迭代器对于不同的容器究竟是怎么取得数据的。
二、C++中的迭代器
2.1泛化指针
在C++中,迭代器通过泛化指针(GeneralizedPointer)的形式呈现。泛化指针与仿函数(Functor)的定义类似,其包含以下两种情况:
是一个真正的指针
不是指针,但重载了某些指针运算符(如“*,++,--,!=”等),使得其行为和指针相似
根据泛化指针为了将其“伪装”成一个真正的指针从而重载的运算符的数量,迭代器被分为五种,如下文所示。
2.2C++的迭代器分类
C++中,迭代器按照其所支持的行为被分为五类:
输入迭代器(InputIterator):仅可作为右值(rvalue),不可作为左值(lvalue)。可以进行比较(“==与!=”)
输出迭代器(OutputIterator):仅可作为左值,不可作为右值
前向迭代器(ForwardIterator):支持一切输入迭代器的操作,以及单步前进操作(++)
双向迭代器(BidirectionalIterator):支持一切前向迭代器的操作,以及单步后退操作(--)
随机访问迭代器(RandomAccessIterator):支持一切双向迭代器操作,以及非单步双向移动操作
对于前向迭代器,双向迭代器,以及随机访问迭代器,如果其不存在底层const(Low-LevelConst)限定,则同时也支持一切输出迭代器操作。
2.3迭代器适配器
C++中还存在一系列迭代器适配器,用于使得一些非迭代器对象的行为类似于迭代器,或修改迭代器的一些默认行为,大致包含如下几个类别:
插入迭代器(InsertIterator):使得对迭代器左值的写入操作变为向容器中插入数据的操作,按插入位置的不同,可分为front_insert_iterator,back_insert_iterator和insert_iterator
反向迭代器(ReverseIterator):对调迭代器的移动方向。使得“+”操作变为向左移动,同时“-”操作变为向右移动(类似于Python的reversed函数)
移动迭代器(MoveIterator):使得对迭代器的取值变为右值引用(RvalueReference)
流迭代器(StreamIterator):使流对象的行为适配迭代器(类似于Python的文件句柄)
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请加danei456学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。