2019独角兽企业重金招聘Python工程师标准>>>

1. 容器(Containers)

容器分为两类:

  1. 序列式容器(Sequence containers),此乃可序群集,其中每个元素均有固定位置————取决于插入时机和地点,和元素值无关。STL提供三个定义好的序列式容器:vector,deque,list
  2. 关联式容器(Associative containers),此乃已序群集,元素位置取决于特定的排序准则,即元素位置取决于元素值,和插入次序无关。STL提供四个关联式容器:set,multiset,map,multimap

1.1 序列式容器

  • Vector Vector将其元素置于一个dynamic array中加以管理,允许随机存取,即可以利用索引直接存取任何一个元素。 在array尾部附加或移除元素非常快速,但在array中部或头部安插元素比较费时

  • Deque Deque与Vector一样,也是一个dynamic array,可以向两端发展,因此不论在尾部或头部安插元素都十分迅速,但在中间部分安插元素则比较费时

  • List 1. List由双向链表实作而成。 2. List不提供随机存取,即List并没有提供以operator[]直接存取元素的能力。 3. List的优势是:在任何位置上执行安插或删除动作都非常迅速。

  • 序列式容器中,向容器首部或末端添加元素分别使用push_front和push_back函数,但vector中并未提供push_front函数

1.2 关联式容器

关联式容器依据特定的排序准则,自动为其元素排序。排序准则以函数形式呈现,用来比较元素值(value)或元素键(key)。缺省情况下以operator<进行比较,也可以提供自己的比较函数,定义不同的排序准则。

  • Set Set的内部元素按其值自动排序,每个元素只能出现一次。
  • Multiset Multiset和Set相同,只不过它允许元素重复。
  • Map Map的元素都是“实值/键值”所形成的一个对组,每个元素都有一个键,是排序准则的基础。每一个键只能出现一次,不允许重复。Map可被视为关联式数组。
  • Multimap Multimap和Map相同,但允许元素重复,即Multimap可包含多个键值相同的元素。Multimap可被当做“字典”
  • **所有关联式容器都有一个可供选择的template参数,指明排序准则。缺省采用operator<。

2. 容器适配器(Container Adapter)

除了上述容器类别,为满足特殊需求,STL提供了一些特别的并预先定义好的容器适配器,包括:

  • Stack Stack容器对元素采取LIFO管理策略。
  • Queue Queue容器对元素采取FIFO管理策略。
  • Priority Queue Priority Queue容器中的元素可以拥有不同的优先级。

3. 迭代器

迭代器是一个“可遍历STL容器内全部或部分元素”的对象。一个迭代器用来指出容器中的一个特定位置。其基本操作如下:

  • operator* 返回当前位置上的元素值。如果该元素拥有成员,你可以透过迭代器,直接以operator->取用它们。
  • operator++、operator-- 将迭代器前进或后退一个元素
  • operator==、operator!= 判断两个迭代器是否指向同一位置。
  • operator= 为迭代器赋值。

3.1 所有容器类别都提供一些成员函数,使我们可以获得迭代器####

  • begin() 返回指向容器起始点的迭代器。
  • end() 返回一个指向容器结束点的迭代器。结束点在最后一个元素之后,这样的迭代器称为“逾尾”迭代器。
  • rbegin() 返回一个指向最后一个元素的逆向迭代器
  • rend() 返回一个指向第一个元素前一个位置的逆向迭代器。

3.2 任何一种容器都定义有两种迭代器性别:

  1. container::iterator 这种迭代器以“读写”模式遍历元素。
  2. Container::const_iterator 这种迭代器以“只读”模式遍历元素。

3.3 迭代器分类

迭代器被划分为5类。STL预先定义好的所有容器中,其迭代器均属于一下两种类型:

  1. 双向迭代器(Bidirectional iterator) 双向迭代器可以双向行进:以++或--运算前进或后退。**list、set、multiset、map和multimap这些容器所提供的迭代器都属于此类。
  2. 随机存取迭代器(Random access iterator) 随机存取迭代器不但具备双向迭代器的所有属性,还具备随机访问能力。更明确的说,他们提供了“迭代器算术运算”必要的操作符(和“一般指针的算术运算符”完全对应)。你可以对迭代器增加或减少一个偏移量、处理迭代器之间的距离、或是使用<和>之类的retational(相对关系)操作符来比较两个迭代器。vector、deque和string所提供的迭代器都属于此类。

为了撰写尽可能与容器型别无关的范型程序代码,最好不要使用随机存取迭代器的特有操作。如下例,可以在任何容器上运作:

for (pos = col.begin();pos != col.end();++pos)
{...
}

而下面的程序代码就不是所有容器都使用了:

for (pos = col.begin();pos < col.end();++pos)
{...
}

因为只有random access iterator才支持operator<。

3.4 迭代器适配器

迭代器是一个纯粹抽象的概念:任何东西,只要其行为类似迭代器,它就是一个迭代器。因此,可以撰写一些类别,具备迭代器接口,但有着各不相同的行为。STL提供了数个预先定义的特殊适配器,即迭代器适配器:

  • Insert iterator(安插型迭代器) 安插型迭代器可以解决算法的“目标空间不足”问题。
  1. Back inserter:内部调用push_back(),在容器尾端插入元素(追加)。
copy (col1.begin(),col1.end(),back_inserter(col2));

当然,只有在提供push_back()成员函数的容器中,back inserter才能派上用场。 2. Front inserter:内部调用push_front(),将元素安插于容器最前端。

copy (col1.begin(),col1.end(),front_inserter(col2));

只有在提供push_front()成员函数的容器中,front inserter才能派上用场,在STL中,这样的容器是deque和list。 3. General inserter:一般性的inserter,它的作用是将元素插入“初始化时接受之第二参数”所指定位置的前方,其内部调用insert()成员函数。所有STL容器都提供有insert()成员函数 |算是(expression)|Insert种类| |-|-| |back_inserter(container)|使用push_back()在容器尾端安插元素,元素排列次序和安插次序相同| |front_inserter(container)|使用push_front()在容器前段安插元素,元素排列次序和安插次序相反| |Insert(container,pos)|使用insert()在pos位置上安插元素,元素排列次序和安插次序相同|

  • Stream interator(流迭代器)
  1. istream_iterator<string>(cin) 产生一个可从“标准输入流cin”中读取数据的stream iterator。元素通过一般的operator>>被读取进来
  2. istream_iterator<string>() 调用istream iterator的default构造函数,产生一个代表“流结束符号”的迭代器。
  3. ostream_iterator<string>(cout,"\n") 产生一个output stream iterator,通过operator<<向cout写入数据,第二个参数(可由可无)被用来作为元素之间的分隔符。
  • Reverse iterator(逆向迭代器) 所有容器都可以通过rbegin()和rend()成员函数产生reverse iterator。

4. 算法(Algorithm)

算法并非容器类别的成员函数,而是一种搭配迭代器使用的全局函数。

  • 优势:所有算法只需实作一份,就可以对所有容器运作,数据与操作被明确划分开来,透过特定的接口彼此互动。
  • 劣势:用法有失直观;某些数据结构和算法之间并不兼容,或者即使兼容也会导致糟糕的效能)。

4.1 区间

  • 所有算法都用来处理一个或多个区间内的元素。
  • 所有算法处理的都是半开区间————包含起始元素位置但不包含结尾元素位置。 [begin,end]

4.2 一些简单的算法

  1. min_element()、max+element() 调用他们时,必须传入两个参数,定义出欲处理的元素范围。
  2. sort() 将由两个参数设定出来的区间内的所有元素加以排序。还可以出入一个排序准则,缺省的是operator<。
  3. find() 在给定范围内搜寻某个值,若成功返回目标元素,若失败,范围一个“逾尾迭代器”,亦即find()所接受的第二个参数。
  4. reverse() 将区间内的元素反转。
  5. distance() 返回两个迭代器之间的距离

4.3 处理多个区间

一些算法可以同时处理多个区间,通常必须设定第一个区间的起点和终点,至于其它区间,你只需设定起点即可,终点通常可由第一区间的元素数量推导出来。下面例子中,equal()从头开始逐一比较col1和col2的所有元素:

if (equal (col1.begin(),col1.end(),col2.begin()))
{...
}

因此,col2中参与比较的元素数量,简洁取决于col1内的元素数量。 所以,如果某个算法用来处理多个区间,那么当你调用它时,务必确保第二区间所拥有的元素个数,至少和第一区间内的元素个数相同。 当然,如果目标区间空间不足,可以使用安插型迭代器

4.4 更易型算法(Manipulating algorithm)

更易型算法是指会“删除或重排或修改元素”的算法。

  1. 移除元素(remove) 算法remove()删除指定区间中的某一元素。
remove (col1.begin(),col1.end(),3);

但remove()算法并没有真正删除某一元素所占的空间,只是将之后的元素向前移动覆盖了某一数值。事实上,remove返回了一个新的终点,利用这个新的终点,通过容器所提供的成员函数,可以彻底删除一个元素。

col1.erase(remove(col1.begin(),col1.end(),3),col1.end());

为何算法不自己直接调用erase()?这就是STL为了获取灵活性而付出的代价。通过“以迭代器为接口”,STL将数据结构和算法分离开来。迭代器只是“容器中某一位置”的抽象概念而已,一般来说,迭代器对自己所属的容器一无所知,任何“以迭代器访问容器元素”的算法,都不得通过迭代器调用容器类别所提供的任何成员函数。

转载于:https://my.oschina.net/u/2602561/blog/751364

STL学习笔记(一)相关推荐

  1. C++ STL学习笔记

    C++ STL学习笔记一 为何要学习STL: 数据结构与算法是编程的核心,STL中包含各种数据结构和优秀的算法,确实值得深入学习,本文中虽然着重使用,但希望有心的朋友能多看看相关数据结构的实现,对于C ...

  2. C++STL学习笔记(4) 分配器(Allocator)

    在前面的博客<C++ STL学习笔记(3) 分配器Allocator,OOP, GP简单介绍>中,简单的介绍了分配器再STL的容器中所担当的角色,这一节对STL六大部件之一的分配器进行详细 ...

  3. C++ STL学习笔记(3) 分配器Allocator,OOP, GP简单介绍

    继续学习侯捷老师的课程! 在前面的博客<C++ STL学习笔记(2) 容器结构与分类>中介绍了STL中常用到的容器以及他们的使用方法,在我们使用容器的时候,背后需要一个东西支持对内存的使用 ...

  4. C++ STL学习笔记 : 1. template 模板函数

    本篇文章是学习C++ STL库的第一篇笔记,主要记录了使用template关键字创建模板函数的方法. 下面用一个非常简单的例子解释模板函数的用法 : #include <iostream> ...

  5. C++ STL学习笔记(2) 容器结构与分类

    接着学习侯捷老师的C++ STL! 在使用容器的时候,需要明白容器中元素之间在内存里的关系是什么样的,是连续的,还是非连续的. 容器可以分为两类: 1. sequence container , 即序 ...

  6. C++ STL 学习笔记__(6)优先级队列priority_queue基本操作

    10.2.7优先级队列priority_queue v  最大值优先级队列.最小值优先级队列 v  优先级队列适配器 STL priority_queue v  用来开发一些特殊的应用,请对stl的类 ...

  7. 【C++ STL学习笔记】C++ STL序列式容器(array,vector,deque,list)

    文章目录 C++ STL容器是什么? 迭代器是什么,C++ STL迭代器(iterator)用法详解 迭代器类别 迭代器的定义方式 C++序列式容器(STL序列式容器)是什么 容器中常见的函数成员 C ...

  8. SGI STL 学习笔记二 vector

    sequence containers Array Vector Heap Priority_queue List sList(not in standard) Deque Stack Queue S ...

  9. C++ STL学习笔记 : 2. unordered map 容器

    本文中,简单总结一下使用unordered map 的心得.unordered_map容器属于STL中关联表的一种,常用的map容器与unordered_map容器在使用中有着很大程度的相同点,在之后 ...

最新文章

  1. 一款DIY矢量网络分析仪:NanoVNA
  2. zynq学习04 zynq中PS通过MIO控制LED
  3. js判断是否在iframe和禁止网页在iframe中显示
  4. https://github.com/fendouai/Awesome-Chatbot
  5. 公司的API接口被刷了,那是因为你没这样做!
  6. 从零开始单排学设计模式「UML类图」定级赛 1
  7. logback 的 access 模块
  8. 前端学习(1188):事件绑定
  9. idea ssm项目移包报错问题
  10. 解决ora-00054 Oracle锁表问题
  11. python list join函数_Python中join()函数多种操作代码实例
  12. python graphviz_Python中Graphviz的输出问题
  13. 阿里云播放器Aliplayer-WEB走坑中
  14. 一行代码下载网页视频!
  15. 用Python玩人脸合成,你也能有一张明星脸(附代码)
  16. miui kindle安装目录
  17. CreateThread函数,无法将参数 3 从“DWORD (__cdecl *)(LPVOID)”转换为“LPTHREAD_START_ROUTINE” PVZCheater
  18. 01-12.产品经理入门到精通(一)
  19. 厦大计算机考研学硕,2021厦大计算机考研招生、复试、书目专业大解析!
  20. 游戏模块分析总结(4)之系统篇

热门文章

  1. command-line: line 0: Bad configuration option: PermitLocalCommand
  2. php5.3.8添加eaccelerator扩展 加速php代码执行效率
  3. [导入]将文字内容和图片插入到Access数据库(转帖)
  4. 共基极放大电路_「模拟电子技术」运算放大电路的共基极、共射极、共集电极接法...
  5. java future用法_Java中的多线程知识点
  6. dnf用虚拟机会被制裁吗_差点把DNF搞关服的私服,这次终于被大话西游手游拿下了...
  7. php查找多个字符串替换,php 替换多个字符串
  8. noj数据结构稀疏矩阵的加法十字链表_数据结构学习(C )稀疏矩阵(十字链表1)
  9. 简述Linux目录结构和系统结构
  10. C 关于使用异或运算操作概述