迭代器

迭代器和生成器

空扰寡人 提交于 2019-11-26 20:31:02
楔子 假如我现在有一个列表l=['a','b','c','d','e'],我想取列表中的内容,有几种方式? 首先,我可以通过索引取值l[0],其次我们是不是还可以用for循环来取值呀? 你有没有仔细思考过,用索引取值和for循环取值是有着微妙区别的。 如果用索引取值,你可以取到任意位置的值,前提是你要知道这个值在什么位置。 如果用for循环来取值,我们把每一个值都取到,不需要关心每一个值的位置,因为只能顺序的取值,并不能跳过任何一个直接去取其他位置的值。 但你有没有想过,我们为什么可以使用for循环来取值? for循环内部是怎么工作的呢? 迭代器 python中的for循环 要了解for循环是怎么回事儿,咱们还是要从代码的角度出发。 首先,我们对一个列表进行for循环。 for i in [1,2,3,4]: print(i) 上面这段代码肯定是没有问题的,但是我们换一种情况,来循环一个数字1234试试 for i in 1234 print(i) 结果: Traceback (most recent call last): File "test.py", line 4, in <module> for i in 1234: TypeError: 'int' object is not iterable 看,报错了!报了什么错呢?“TypeError: 'int' object

C++标准库(七)之traits技术

有些话、适合烂在心里 提交于 2019-11-26 20:18:21
C++标准库(七)之traits技术 traits技术 原理:利用template的参数推导机制获取传入的参数型别。 template<typename T> struct Iter { typedef T value_type; .... } template<typename T> typename T::value_type func(T* ite) {return *ite;} 这种程度,依旧会遇到一个问题:如果不是一个class type(比如指针,引用),就无法进行正确的参数推导。可以使用模板偏特化来处理这种情形: template<typename T> struct Iter<T*> { typename T value_type; }; 我们需要处理的核心问题: 通过traits技术如何获得iterator描述的型别? template<typename T> struct iterator_traits { typedef typename T::iterator_category iterator_category; typedef typename T::value_type value_type; typedef typename T::difference_type difference_type; typedef typename T::pointer

C++标准库(九)之iterator

我的未来我决定 提交于 2019-11-26 20:17:50
C++标准库(九)之iterator iterator iterator模式:提供一种方法,使之能依次访问容器内的各个元素,而又不暴露该聚合物内部的表述方式。 STL的中心思想是将算法与数据结构分离,彼此独立设计,最后在用iterator将他们结合在一起,获得最大的适配性。 vector 设计理念 vector是动态空间,随着元素的加入,内部机制会自动扩充空间以容纳新元素。vector的实现技术核心在于: 对容器大小的控制以及重新配置时数据的移动效率 。 空间配置策略 :在原容器无可用空间时,将容器大小扩展为原先的两倍,然后将原先的数据copy,在copy的数据后面构造新元素。 数据移动效率 :根据是否为POD类型判断移动数据的成本,并想进一切方法减少数据移动的次数,源码中有详解。 迭代器定义 vector在进行萃取的时候,会使用萃取提供的特化版本: template<typename T> struct iterator_traits<T*> {} template<typename T,class Alloc=alloc> class vector { public: typedef T value_type; typedef value_type* pointer; typedef value_type* iterator; typedef value_type&

C++标准库(一)之新语言特性

▼魔方 西西 提交于 2019-11-26 20:15:39
C++标准库(一)之新语言特性 新语言特性 nullptr 被解释为一个 void* ,不同于 NULL 被解释为一个 int 可以用 auto 在编译期完成自动推导,不会影响执行期的速度 新的 for 循环方式: for(decl : coll) { statement } rvalue reference 也是一个 reference ,也就是说,下面这段代码是无效的: X&& foo() { X x; return std::move(x); } 关键字: expllicit 意味着在对象构造期间不能有显式类型转换 关键字: noexcept 用来表示某个函数不打算抛出异常。异常出现在运行期而非编译期,但是运行期的异常会使得编译器产生额外的指令代码。可在析构函数,swap函数,move构造函数和move assignment操作符使用此声明。总之,和资源管理相关的函数都不应该抛出异常. void foo() noexcept 关键字: constexpr 可用来让表达式核定于编译器。 关键字: mutable 修饰任何情况下都可变的变量,即使该变量被 const 修饰 Lambda表达式: int x,y; auto lambda = [x,&y]()->double{return 42+x*y;}; 关键字: decltype 用于描述表达式类型,两种基本用法: int x

【算法•日更•第三十八期】迭代器是什么?

守給你的承諾、 提交于 2019-11-26 19:57:32
▎写在前面   之前一直听别人说用什么迭代器之类的话,认为很高深,今天看了看,感觉也不是很高深。   其实和指针差不多。 ▎迭代器 ☞ 『定义』 迭代器( iterator )是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。迭代器修改了常规 指针 的接口,所谓迭代器是一种概念上的抽象:那些行为上像迭代器的东西都可以叫做迭代器。然而迭代器有很多不同的能力,它可以把 抽象 容器和通用算法有机的统一起来。 迭代器提供一些基本操作符:*、++、==、!=、=。这些操作和C/C++“操作array元素”时的指针接口一致。不同之处在于,迭代器是个所谓的复杂的指针,具有遍历复杂数据结构的能力。其下层运行机制取决于其所遍历的数据结构。因此,每一种容器型都必须提供自己的迭代器。事实上每一种容器都将其迭代器以嵌套的方式定义于内部。因此各种迭代器的接口相同,型号却不同。这直接导出了 泛型 程序设计的概念:所有操作行为都使用相同接口,虽然它们的型别不同。(copy自百度) ☞ 『迭代器』   我们往往会用到容器,什么容器呢? 锅碗瓢盆、 数组、vector、queue之类的都是。   对于这种东西,我们往往要执行一些操作,比如说查找元素之类的,迭代器就是专门用来访问容器的一种数据类型。   可以说迭代器就是复杂的指针,指针是狭义上的迭代器。 ☞ 『迭代器

二叉搜索树迭代器

六月ゝ 毕业季﹏ 提交于 2019-11-26 19:14:16
实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。 调用 next() 将返回二叉搜索树中的下一个最小的数。 示例: BSTIterator iterator = new BSTIterator(root); iterator.next(); // 返回 3 iterator.next(); // 返回 7 iterator.hasNext(); // 返回 true iterator.next(); // 返回 9 iterator.hasNext(); // 返回 true iterator.next(); // 返回 15 iterator.hasNext(); // 返回 true iterator.next(); // 返回 20 iterator.hasNext(); // 返回 false 提示: next() 和 hasNext() 操作的时间复杂度是 O(1),并使用 O(h) 内存,其中 h 是树的高度。 你可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 中至少存在一个下一个最小的数。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/binary-search-tree-iterator 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

极*Java速成教程 - (5)

℡╲_俬逩灬. 提交于 2019-11-26 19:05:16
Java语言基础 容器 这个世界是有序的,将Java对象零散地放到内存中是不符合世界常理的,特别是有一大组相似的甚至不知道有多少数据的时候。把Java对象装进盒子里可以有序收纳,这个盒子就叫容器。 初次了解泛型 泛型,就是泛泛而指的类型,就是不确定具体类型的类型。Java提供的容器,一般都支持泛型,也就是说不管是什么对象,都可以丢到容器中进行收纳。但在Java中,所有类都继承自Object,所以把对象当作Object对象丢到容器里不会有任何问题,但当拿出来这个Object的时候,由于不知道这个对象的真正类型是什么,就可能在向下转型的时候出现错误,为了避免这种情况,一般对容器使用 <type> 表示容器的具体类型参数,也就是容器里放什么类就确定了,编译器就会对类型进行检查,避免运行时Object对象向下转型时错误的发生。例如: List<Apple> apples = new ArrayList<Apple>(); 你应当创建一个具体类的对象,将其转型为对应的接口,然后在其余的代码中都使用这个接口。 容器的类型 Collection 一个独立元素的序列,符合某种规则,提供迭代器,可以用foreach进行迭代遍历,也就是提供一个方法,可以每次从序列中从前到后依次拿到每一个元素。 List 有序的序列,对象元素按照插入顺序保存 ArrayList 连续储存的List,可以使用数字来查找值

三十分钟学习STL【转载】

≯℡__Kan透↙ 提交于 2019-11-26 18:36:52
原文: http://net.pku.edu.cn/~yhf/UsingSTL.htm 太长30分钟是看不完的,不过花一个小时把他看完能对STL有个大致的了解,g++下需要加iterator头文件 以下为原文 这是本小人书。原名是《using stl》,不知道是谁写的。不过我倒觉得很有趣,所以化了两个晚上把它翻译出来。我没有对翻译出来的内容校验过。如果你没法在三十分钟内觉得有所收获,那么赶紧扔了它。文中我省略了很多东西。心疼那,浪费我两个晚上。 译者:kary contact:karymay@163.net STL概述 STL的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但这种分离确实使得STL变得非常通用。例如,由于STL的sort()函数是完全通用的,你可以用它来操作几乎任何数据集合,包括链表,容器和数组。 要点 STL算法作为模板函数提供。为了和其他组件相区别,在本书中STL算法以后接一对圆括弧的方式表示,例如sort()。 STL另一个重要特性是它不是面向对象的。为了具有足够通用性,STL主要依赖于模板而不是封装,继承和虚函数(多态性)——OOP的三个要素。你在STL中找不到任何明显的类继承关系。这好像是一种倒退,但这正好是使得STL的组件具有广泛通用性的底层特征。另外,由于STL是基于模板,内联函数的使用使得生成的代码短小高效。 提示

STL标准入门汇总【转载】

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-26 18:36:46
原文: http://www.cnblogs.com/shiyangxt/archive/2008/09/11/1289493.html 第一部分:(参考百度百科) 一、 STL 简介 STL ( Standard Template Library ,标准模板库 ) 是惠普实验室开发的一系列软件的统称。它是由 Alexander Stepanov 、 Meng Lee 和 David R Musser 在惠普实验室工作时所开发出来 的。现在虽说它主要出现在 C++ 中,但在被引入 C++ 之前该技术就已经存在了很长的一段时间。 STL 的代码从广义上讲分为三类: algorithm (算法)、 container (容器)和 iterator (迭代器),几乎所有的代码都采用了模板类和模版函数的方式,这相比于传统的由函数和类 组成的库来说提供了更好的代码重用机会。在 C++ 标准中, STL 被组织为下面的 13个头文件 : <algorithm> 、 <deque> 、 <functional> 、 <iterator> 、 < vector>、 <list>、<map>、 <memory> 、 <numeric> 、 <queue> 、 <set> 、 <stack> 和 <utility> 。 二、算法

STL map部分用法示例

白昼怎懂夜的黑 提交于 2019-11-26 18:36:33
1. map的构造函数 map共提供了6个构造函数,这块涉及到内存分配器这些东西,略过不表,在下面我们将接触到一些map的构造方法,这里要说下的就是,我们通常用如下方法构造一个map: map< int , string > mapStudent; 2. 数据的插入 在构造map容器后,我们就可以往里面插入数据了。这里讲三种插入数据的方法: 第一种:用insert函数插入pair数据 #include <map> #include <stdlib.h> #include <iostream> #include < string > using namespace std; int main ( int argc, char * argv[] ) { map < int , string > mapStudent; map < int , string > ::iterator iter; mapStudent.insert (pair < int , string > ( 1 , " One " )); mapStudent.insert (pair < int , string > ( 2 , " Two " )); mapStudent.insert (pair < int , string > ( 3 , " Three " )); for (iter =