STL
Content
简介
容器
迭代器
算法
简介
首先为什么不叫标准库,而叫标准模板库呢?原因在于它突出模板(即泛型)的概念。
stl由三部分组成:容器,迭代器,算法。下面分别做一个简略介绍:
stl的哲学是将数据和操作分离。数据由容器管理,操作由可定制的算法定义,迭代器充当了两者之间的的粘合剂。
(*) 容器
序列式容器(sequence container): vector, deque, list
元素的位置取决于插入的时机
关联式容器(associative container): set, multiset(允许元素重复的set), map, multimap(允许元素重复的map)
元素的位置取决于排序规则。内部实现方式都是二叉树。
map其实可以看成set,只不过元素是pair,分成了key(first)和value(second),另外只有key不允许冲突。multimap则连key也可以重复。
用map可以用以下方式插入、修改元素,可当作关联数组来使用,这一点multimap做不到:
map<string, int> scores;
scores["James"] = 76;
scores["Stevens"] = 89;
multiple允许key重复,这一点map做不到。
(*) 迭代器
迭代器用来在一个容器内行进,而不管这个容器具体是数组、链表或是树。因为每个容器都提供了自己的迭代器的实现。
begin()指向第一个元素,end()指向最后一个元素的后面。若container为空,则begin() == end()。
迭代器只不过是“容器中某一位置”的抽象概念,它对自己所属的容器一无所知,任何以迭代器访问容器的算法都无法通过迭代器调用容器类型的成员函数。
尽量用iter != end()来判断结尾,而不是iter < end(),因为只有vector, deque, list的迭代器才支持<运算符。
(*) 算法
算法并非容器的成员函数,而是搭配迭代器使用的全局函数。
算法vs成员函数
总的来说,算法更通用,成员函数更有针对性。
成员函数的优点:
如果追求高效率,应优先选用成员函数。例如对list使用remove算法就不如使用.remove成员函数效率高。
成员函数的缺点:
一旦换另一种容器,就不得不更动程序代码.
容器
对应用程序员来讲,容器毫无疑问是STL中最有价值的部分。学习容器应从两个方面入手:
1各种容器的适用情况
2了解容器的接口
下面列出了各种容器的比较:
搜索元素并不一定要用set或map之类的二叉树结构,应具体情况具体分析。
例如,若元素个数较少,直接用vector就好,因为vector的结构是所有容器中最简单的。
如果对搜索性能要求极为苛刻,不妨用hash table,虽然它不在STL中,但很多库已经实现了hash table。
关于容器的使用细节,有一些资源可以参考:
网站:http://www.cplusplus.com/reference/stl/
书籍:C++ Standard Library 6.10
迭代器
Iterator Category | Ability | Providers |
---|---|---|
Input iterator | Reads forward | istream |
Output iterator | Writes forward | ostream, inserter |
Forward iterator | Reads and writes forward | |
Bidirectional iterator | Reads and writes forward and backward | list, set, multiset, map, multimap |
Random access iterator | Reads and writes with random access | vector, deque, string, array |
forward迭代器是input和output迭代器的结合,而且还能在同一个元素上“驻留”。
bidirectional迭代器在forward迭代器的基础上增加了回头遍历的功能,即--操作。
random access迭代器能使用数字索引,还能使用比较运算符比较同一容器中不同迭代器的前后位置。
算法
STL提供了几乎所有的常用算法。但这一部分内容相对琐碎,而且最好能预先掌握仿函数、iterator adapter这样的高级概念,门槛较高。所以先不深入了,等以后真用到再说。
仿函数参见C++ standard library Ch9
iterator adapter参见C++ standard library Ch7.4