100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > C++ 笔记(19)— 标准模板库(STL容器 STL迭代器 STL算法 STL容器特点 STL字符串类)

C++ 笔记(19)— 标准模板库(STL容器 STL迭代器 STL算法 STL容器特点 STL字符串类)

时间:2018-10-15 05:39:22

相关推荐

C++ 笔记(19)— 标准模板库(STL容器 STL迭代器 STL算法 STL容器特点 STL字符串类)

C++标准库可以分为两部分:

标准函数库: 这个库是由通用的、独立的、不属于任何类的函数组成的。函数库继承自C语言。面向对象类库: 这个库是类及其相关函数的集合。

C++标准库包含了所有的C标准库,为了支持类型安全,做了一定的添加和修改。

标准函数库

标准函数库分为以下几类:

输入/输出 I/O字符串和字符处理数学时间、日期和本地化动态分配其他宽字符函数

面向对象类库

标准的C++面向对象类库定义了大量支持一些常见操作的类,比如输入/输出 I/O、字符串处理、数值处理。面向对象类库包含以下内容:

标准的 C++ I/O 类String 类数值类STL 容器类STL 算法STL 函数对象STL 迭代器STL 分配器本地化库异常处理类杂项支持库

简单地说,标准模板库(STL)是一组模板类和函数,向程序员提供了:

用于存储信息的容器;用于访问容器存储的信息的迭代器;用于操作容器内容的算法。

1. STL 容器

容器是用于存储数据的STL类,STL提供了两种类型的容器类:

顺序容器;关联容器。

另外,STL还提供了被称为容器适配器(Container Adapter)的类,它们是顺序容器和关联容器的变种,包含的功能有限,用于满足特殊的需求。

1.1 顺序容器

顾名思义,顺序容器按顺序存储数据,如数组和列表。顺序容器具有插入速度快但查找操作相对较慢的特征。

STL顺序容器如下所示。

std::vector:操作与动态数组一样,在最后插入数据;可将vector视为书架,您可在一端添加和拿走图书。

std::deque:与std::vector类似,但允许在开头插入或删除元素。

std::list:操作与双向链表一样。可将它视为链条,对象被连接在一起,您可在任何位置添加或删除对象。

std::forward_list:类似于std::list,但是单向链表,只能沿一个方向遍历。

STL vector类与数组类似,允许随机访问元素,即可使用下标运算符[]指定元素在vector中的位置(索引),从而直接访问或操作元素。另外,STL vector是动态数组,因此能够根据应用程序在运行阶段的需求自动调整长度。

为保留数组能够根据位置随机访问元素的特征,大多数STL vector实现都将所有元素存储在连续的存储单元中,因此需要调整长度的vector通常会降低应用程序的性能,这取决于它包含的对象类型。

可将STL list类视为普通链表的STL实现。虽然list中的元素不能像STL vector中的元素那样随机访问,但list可使用不连续的内存块组织元素,因此它不像std::vector那样需要给内部数组重新分配内存,进而导致性能问题。

1.2 关联容器

关联容器按指定的顺序存储数据,就像词典一样。这将降低插入数据的速度,但在查询方面有很大的优势。

STL提供的关联容器如下所示。

std::set:存储各不相同的值,在插入时进行排序;容器的复杂度为对数。std::unordered_set:存储各不相同的值,在插入时进行排序;容器的复杂度为常数。这种容器是 C++11 新增的。std::map:存储键-值对,并根据唯一的键排序;容器的复杂度为对数。std::unordered_map:存储键-值对,并根据唯一的键排序;容器的复杂度为对数。这种容器是 C++11 新增的。std::multiset:与set类似,但允许存储多个值相同的项,即值不需要是唯一的。std::unordered_multiset:与unordered_set类似,但允许存储多个值相同的项,即值不需要是唯一的。这种容器是 C++11 新增的。std::multimap:与map类似,但不要求键是唯一的。std::unordered_multimap:与unordered_map类似,但不要求键是唯一的。这种容器是 C++11 新增的。

1.3 容器适配器

容器适配器(Container Adapter)是顺序容器和关联容器的变种,其功能有限,用于满足特定的需求。主要的适配器类如下所示。

std::stack:以LIFO(后进先出)的方式存储元素,让您能够在栈顶插入(压入)和删除(弹出)元素。std::queue:以FIFO(先进先出)的方式存储元素,让您能够删除最先插入的元素。std::priority_queue:以特定顺序存储元素,因为优先级最高的元素总是位于队列开头。

2. STL 迭代器

最简单的迭代器是指针。给定一个指向数组中的第一个元素的指针,可递增该指针使其指向下一个元素,还可直接对当前位置的元素进行操作。

STL中的迭代器是模板类,从某种程度上说,它们是泛型指针。这些模板类让程序员能够对STL容器进行操作。注意,操作也可以是以模板函数的方式提供的STL算法,迭代器是一座桥梁,让这些模板函数能够以一致而无缝的方式处理容器,而容器是模板类。

STL提供的迭代器分两大类。

输入迭代器:通过对输入迭代器解除引用,它将引用对象,而对象可能位于集合中。最严格的输入迭代器确保只能以只读的方式访问对象。

输出迭代器:输出迭代器让程序员对集合执行写入操作。最严格的输出迭代器确保只能执行写入操作。

上述两种基本迭代器可进一步分为三类。

前向迭代器:这是输入迭代器和输出迭代器的一种细化,它允许输入与输出。前向迭代器可以是const的,只能读取它指向的对象;也可以改变对象,即可读写对象。前向迭代器通常用于单向链表。双向迭代器:这是前向迭代器的一种细化,可对其执行递减操作,从而向后移动。双向迭代器通常用于双向链表。随机访问迭代器:这是对双向迭代器的一种细化,可将其加减一个偏移量,还可将两个迭代器相减以得到集合中两个元素的相对距离。随机访问迭代器通常用于数组。

3. STL 算法

查找、排序和反转等都是标准的编程需求,不应让程序员重复实现这样的功能。因此STLSTL算法的方式提供这些函数,通过结合使用这些函数和迭代器,程序员可对容器执行一些最常见的操作。

最常用的STL算法如下所示。

std::find:在集合中查找值。std::find_if:根据用户指定的谓词在集合中查找值。std::reverse:反转集合中元素的排列顺序。std::remove_if:根据用户定义的谓词将元素从集合中删除。std::transform:使用用户定义的变换函数对容器中的元素进行变换。

这些算法都是std命名空间中的模板函数,要使用它们,必须包含标准头文件<algorithm>

4. 迭代器在容器和算法之间交互

下面程序使用了STL顺序容器std::vector(它类似于动态数组)来存储一些整数,再使用std::find算法在集合中查找一个整数。请注意迭代器是如何在这两者之间搭建桥梁的。

#include <iostream>#include <vector>#include <algorithm>using namespace std;int main (){// A dynamic array of integersvector <int> intArray;// Insert sample integers into the arrayintArray.push_back (50);intArray.push_back (2991);intArray.push_back (23);intArray.push_back (9999);cout << "The contents of the vector are: " << endl;// Walk the vector and read values using an iteratorvector <int>::iterator arrIterator = intArray.begin ();while (arrIterator != intArray.end ()){// Write the value to the screencout << *arrIterator << endl;// Increment the iterator to access the next element++ arrIterator;}// Find an element (say 2991) using the 'find' algorithmvector <int>::iterator elFound = find (intArray.begin () , intArray.end (), 2991);// Check if value was foundif (elFound != intArray.end ()){// Determine position of element using std::distanceint elPos = distance (intArray.begin (), elFound);cout << "Value "<< *elFound;cout << " found in the vector at position: " << elPos << endl;}return 0;}

输出结果:

The contents of the vector are: 502991239999Value 2991 found in the vector at position: 1

上述代码演示了如何使用迭代器遍历向量。迭代器是一个接口,将算法(find)连接到其要操作的数据所属的容器(如vector)。

第 20 行声明了迭代器对象arrIterator,并将其初始化为指向容器开头,即vector的成员函数begin()返回的值。

第 22~29 行演示了如何在循环中使用该迭代器遍历并显示vector包含的元素,这与显示静态数组的内容极其相似。迭代器的用法在所有STL容器中都相同。

所有容器都提供了begin()函数和end()函数,其中前者指向第一个元素,后者指向容器中最后一个元素的后面。这就是第 22 行的while循环在end()前面而不是end()处结束的原因。

第 32 行演示了如何使用findvector中查找值。find操作的结果也是一个迭代器,通过将该迭代器与容器末尾进行比较,可判断find是否成功,如第 36 行所示。如果找到了元素,便可对该迭代器解除引用(就像对指针解除引用一样)以显示该元素。

算法distance计算找到的元素的所处位置的偏移量。上述代码所有的vector都替换为deque,代码仍能通过编译并完美地运行。这表明迭代器让您能够轻松地使用算法和容器。

5. STL 容器类特点

6. STL 字符串类

STL提供了一个专门为操纵字符串而设计的模板类:std::basic_string<T>,该模板类的两个常用具体化如下所示。

std::string:基于charstd::basic_string具体化,用于操纵简单字符串。std::wstring:基于wchar_tstd::basic_string具体化,用于操纵宽字符串,通常用于存储支持各种语言中符号的Unicode字符。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。