Generic Programming I
第1讲 初识STL - 1 -
§1.1 什么是泛型程序设计 - 1 -
§1.2 什么是STL - 1 -
§1.3 STL的核心组件 - 2 -
§1.3.1 容器(container) - 3 -
§1.3.2 算法(algorithm) - 3 -
§1.3.3 迭代器(Iterrator) - 4 -
§1.3.4 函数对象(function object) - 5 -
§1.3.5 容器、迭代器、算法和函数对象之间的关系 - 8 -
§1.4 建立STL程序的方法 - 8 -
第2讲 STL容器 - 11 -
§2.1 序列式容器 - 11 -
§2.1.1 Vectors.............................................................- 11 -
§2.1.2 Deques…………………………………………………………………...- 20 -
§2.1.3 Lists……………………………………………………………………….- 23 -
§2.2 关联式容器 - 30 -
§2.2.1 操作Set 和Multisets的成员函数及算法 - 30 -
§2.2.2 Set 和Multisets应用实例 - 32 -
§2.2.3 操作Maps和Multimaps的成员函数 - 32 -
§2.2.4 Maps和Multimaps应用实例 - 35 -
§2.3 特殊容器——顺序容器配接器 - 38 -
§2.3.1 Stack(栈).......................................................................................... - 38 -
§2.3.2 Queue(队列).................................................................................... - 40 -
§2.3.3 Priority Queues(优先级队列) - 41 -
§2.4 Strings可以视为一种STL容器 - 43 -
第3讲 STL迭代器 - 46 -
§3.1 迭代器 - 46 -
§3.2 迭代器的分类(Iterator Categorise) - 48 -
§3.3 迭代器的算术操作 - 48 -
§3.4 迭代器的区间 - 49 -
§3.5 迭代器的辅助函数 - 51 -
§3.5.1 函数advance(p, n) - 51 -
§3.5.2 函数distance(first, last) - 52 -
§3.5.3 函数Iter_swap(p1,p2) - 53 -
§3.6 迭代器适配器(Iterator Adapters) - 54 -
§3.6.1 Insert Iterators(安插型迭代器) - 54 -
§3.6.2 Stream Iterators(流迭代器) - 56 -
§3.6.3 Reverse Iterators(逆向迭代器) - 58 -
第4讲 STL函数对象 - 60 -
§4.1 什么是函数对象 - 60 -
§4.2 标准库中预定义的函数对象 - 62 -
§4.3 STL中一元函数对象与二元函数对象的基类 - 66 -
§4.4 函数适配器 - 69 -
§4.5 STL预定义函数对象应用示例 - 74 -
第5讲 STL算法 - 76 -
§5.1 非变异算法 - 80 -
§5.2 变异算法 - 89 -
§5.3 排序算法 - 96 -
§5.4 数值算法 - 102 -
附录 STL基本容器常用成员函数一览 - 106 -
§1 各类容器共性成员函数 - 106 -
§2 顺序容器和关联容器共有函数 - 106 -
§3 容器比较 - 106 -
§4 vector容器常用成员函数 - 106 -
§5 deque容器常用成员函数 - 107 -
§6 list容器常用成员函数 - 108 -
§7 队列和堆栈常用成员函数 - 109 -
§8 优先队列常用成员函数 - 110 -
§9 集合常用成员函数 - 110 -
§10 映射常用成员函数 - 111 -
第1讲 初识STL
§1.1 什么是泛型程序设计
所谓泛型程序设计(Generic Programming,GP),就是编写不依赖于具体数据类型的程序。C++中的模板(包括函数模版与类模版)是泛型程序设计的主要工具。
泛型程序设计的主要思想是将算法从特定的数据结构中分离出来,使算法成为通用的、可以适用于各种不同类型的容器 (数据结构)。这样就不必为每种容器都写一套同样的算法,从而提高了软件的复用性。
显然,泛型程序设计更加通用。
§1.2 什么是STL
STL(Standard Template Library,标准模板库)是一个高效的C++程序库。它被容纳于C++标准程序库(C++ Standard Library)中,是ANSI/ISO C++标准中最新的也是极具革命性的一部分。该库包含了诸多在计算机科学领域里常用的基本数据结构和基本算法。为广大C++程序员们提供了一个可扩展的应用框架,高度体现了软件的可复用性。
从逻辑层次来看,在STL中体现了泛型程序设计的思想,引入了诸多新的概念,比如像容器(container)、算法(algorithmn)以及迭代器(iterator)等。与OOP中的多态(polymorphism)一样,泛型也是一种软件复用技术。
从实现层次看,整个STL是以类型参数化(type parameterized)的方式实现的。这种方式完全基于C++标准中的模板(template),也就是说,整个STL几乎都是类模板和函数模板。
图1-1 STL和C++标准函数库的组件
STL最初是由HP公司被誉为STL之父的Alexander Stepanov(出生于莫斯科)和Meng Lee开发的一个用于支持C++泛型编程的模板库,1998年被纳入C++标准,成为C++ 标准库的一部分,如图1-1所示。STL是C++发展的重要里程碑。由于C++标准库有多种不同的实现,因此,STL也有多种版本,但它们为用户提供的接口都遵守共同的标准。
§1.3 STL的核心组件
STL主要包含容器、算法、迭代器三大核心部分:
■ STL容器包含了绝大多数数据结构,如数组、链表、字符串、队列、堆栈、树等;
■ STL算法包含了诸如增、删、改、查、排序等系统(全局)函数模板。这些算法都是泛型算法,同一个算法可以适用于任意类型的容器;
■ STL 迭代器类似指针一样,通过它的有序移动,把容器中的元素与算法关联起来,它是实现所有STL功能的基础所在。
下面首先看一个简单的STL程序。
【例1-1】从标准输入设备键盘依次输入5个整数5、-3、1、0和8,存入一个向量容器中,然后输出它们的相反数。
#include
#include //向量头文件
#include //迭代器头文件
#include //算法头文件
#include //函数对象(仿函数)头文件
using namespace std; //导入命名空间std
void main() {
const int N = 5;
vector s(N); //定义一个含有5个int类型数据元素的向量容器对象s
vector::iterator pos; //声明一个向量迭代器pos,该向量元素为int型
for (int i = 0; i < N; ++i)
cin >> s[i]; //从键盘依次输入整数5、-3、1、0和8
//显然,向量容器可以随机访问
cout<<"从键盘输入的5个整数是:"<(cout, ", "), negate());
cout << endl;
}
程序运行的结果如图1-2所示。
图1-2 例1-1的运行结果
例1-1虽然简单,但却涉及到了STL的3种最关键、最核心的组件:容器(Container)、算法(Algorithms)与迭代器(Iterator)。除此之外,STL还有函数对象(Function object)、容器适配器(container adaptor)以及STL的其它标准组件。在早期的STL版本中,函数对象又称为仿函数(functor)。下面分别对它们做简单介绍,在后面还要分门别类地比较深入地介绍它们。
§1.3.1 容器(container)
STL中的容器是一种存储有限个T(Template)类型数据元素的集合,每种容器都是一种数据结构。数据元素可以是类的对象本身,如果数据类型T代表的是Class的话。当然,这些数据元素也可以是其它数据类型的数据。例1-1中的s就是一种容器对象,叫做向量容器。容器的内部实现是类模板。
STL提供了七种基本容器,它们被划分为两大类,即序列式容器(Sequence Containers)和关联式容器(Associatve Containers)。除了基本容器外,STL还提供了一些其它类型的容器,如容器适配器(容器适配器可以看作是由其它容器实现的容器)。
序列式容器中的元素顺序与元素值无关,只与元素插入的次序和存放位置有关。STL预先定义了三种序列式容器,即Vectors(向量)、Deque(双向队列)和List(双向链表)。
关联式容器中的元素位置是按元素值的大小自动排序的,缺省情况下为升序排列。其元素顺序与元素值有关,与元素插入的先后次序无关。关联式容器的底层实现是二叉搜索树的形式。STL中预先定义的关联式容器有Sets与Multisets(集合与多重集合)以及Map与Multimap(映射与多重映射) 。
注意,在C++标准中,STL的组件被组织为13个头文件:、、、、