C++STL复习
参考文献
STL组成
STL组成
含义
容器
一些封装数据结构的模板类,例如 vector 向量容器、list 列表容器等。
算法
STL 提供了非常多(大约 100 个)的数据结构算法,它们都被设计成一个个的模板函数,这些算法在 std 命名空间中定义,其中大部分算法都包含在头文件 中,少部分位于头文件 中。
迭代器
在 C++ STL 中,对容器中数据的读和写,是通过迭代器完成的,扮演着容器和算法之间的胶合剂。
函数对象
如果一个类将 () 运算符重载为成员函数,这个类就称为函数对象类,这个类的对象就是函数对象(又称仿函数)。
适配器
可以使一个类的接口(模板的参数)适配成用户指定的形式,从而让原本不能在一起工作的两个类工作在一起。值得一提的是,容器、迭代器和函数都有适配器。
内存分配器
为容器类模板提供自定义的内存申请和释放功能,由于往往只有高级用户才有改变内存分配策略的需求,因此内存分配器对于一般用户来说,并不常用。
迭代器
定义
迭代器定义方式
具体格式
正向迭代器
容器类名::iterator 迭代器名;
常量正向迭代器
容器类名::const_iterator 迭代器名;
反向迭代器
容器类名::reverse_iterator 迭代器名;
常量反向迭代器
容器类名::const_reverse_iterator 迭代器名;容器
序列式容器
包括 array、vector、deque、list 和 forward_list 容器。
vector
#include
using namespace std;
创建
std::vector<double> values;
std::vector<double> values(20); //指定元素个数
std::vector<int> primes {2, 3, 5, 7, 11, 13, 17, 19};
std::vector<double> values(20, 1.0);//初始值默认为1.0int num=20;
double value =1.0;
std::vector<double> values(num, value); //也可以是变量std::vector<char>value1(5, ‘c’);
std::vector<char>value2(value1);//用已有的容器创建int array[]={1,2,3};
std::vector<int>values(array, array+2);//values 将保存{1,2}
std::vector<int>value1{1,2,3,4,5};
std::vector<int>value2(std::begin(value1),std::begin(value1)+3);//value2保存{1,2,3}std可省去
增加容量
values.reserve(20);
迭代器用法
//遍历 vector 容器。
#include
//需要引入 vector 头文件
#include
using namespace std;
int main()
{
vector<int> v{1,2,3,4,5,6,7,8,9,10}; //v被初始化成有10个元素
cout << “第一种遍历方法:” << endl;
//size返回元素个数
for (int i = 0; i < v.size(); ++i)
cout << v[i] <<” “; //像普通数组一样使用vector容器
//创建一个正向迭代器,当然,vector也支持其他 3 种定义迭代器的方式
cout << endl << “第二种遍历方法:” << endl;
vector<int>::iterator i;
//用 != 比较两个迭代器
for (i = v.begin(); i != v.end(); ++i)
cout << *i << “ “;
cout << endl << “第三种遍历方法:” << endl;
for (i = v.begin(); i < v.end(); ++i) //用 < 比较两个迭代器
cout << *i << “ “;
cout << endl << “第四种遍历方法:” << endl;
i = v.begin();
while (i < v.end()) { //间隔一个输出
cout << *i << “ “;
i += 2; // 随机访问迭代器支持 “+= 整数” 的操作
}
}成员函数
函数成员
函数功能
begin()
返回指向容器中第一个元素的迭代器。
end()
返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用。
rbegin()
返回指向最后一个元素的迭代器。
rend()
返回指向第一个元素所在位置前一个位置的迭代器。
cbegin()
和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
cend()
和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crbegin()
和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crend()
和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
size()
返回实际元素个数。
max_size()
返回元素个数的最大值。这通常是一个很大的值,一般是 232-1,所以我们很少会用到这个函数。
resize()
改变实际元素的个数。
capacity()
返回当前容量。
empty()
判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
reserve()
增加容器的容量。
shrink _to_fit()
将内存减少到等于当前元素实际所使用的大小。
operator[ ]
重载了 [ ] 运算符,可以向访问数组中元素那样,通过下标即可访问甚至修改 vector 容器中的元素。
at()
使用经过边界检查的索引访问元素。
front()
返回第一个元素的引用。
back()
返回最后一个元素的引用。
data()
返回指向容器中第一个元素的指针。
assign()
用新元素替换原有内容。
push_back()
在序列的尾部添加一个元素。
pop_back()
移出序列尾部的元素。
insert()
在指定的位置插入一个或多个元素。
erase()
移出一个元素或一段元素。
clear()
移出所有的元素,容器大小变为 0。
swap()
交换两个容器的所有元素。
emplace()
在指定的位置直接生成一个元素。
emplace_back()
在序列尾部生成一个元素。
C++ 11 标准库还新增加了 begin() 和 end() 这 2 个函数,和 vector 容器包含的 begin() 和 end() 成员函数不同,标准库提供的这 2 个函数的操作对象,既可以是容器,还可以是普通数组。当操作对象是容器时,它和容器包含的 begin() 和 end() 成员函数的功能完全相同;如果操作对象是普通数组,则 begin() 函数返回的是指向数组第一个元素的指针,同样 end() 返回指向数组中最后一个元素之后一个位置的指针(注意不是最后一个元素)。
array(c++11)
关联式容器
关联式容器则大不一样,此类容器在存储元素值的同时,还会为各元素额外再配备一个值(又称为“键”,其本质也是一个 C++ 基础数据类型或自定义类型的元素),它的功能是在使用关联式容器的过程中,如果已知目标元素的键的值,则直接通过该键就可以找到目标元素,而无需再通过遍历整个容器的方式。
底层选用了 「红黑树」这种数据结构来组织和存储各个键值对。
C++ STL 标准库提供了 4 种关联式容器,分别为 map、set、multimap、multiset
关联式容器名称
特点
map
定义在 头文件中,使用该容器存储的数据,其各个元素的键必须是唯一的(即不能重复),该容器会根据各元素键的大小,默认进行升序排序(调用 std::less)。
set
定义在 头文件中,使用该容器存储的数据,各个元素键和值完全相同,且各个元素的值不能重复(保证了各元素键的唯一性)。该容器会自动根据各个元素的键(其实也就是元素值)的大小进行升序排序(调用 std::less)。
multimap
定义在 头文件中,和 map 容器唯一的不同在于,multimap 容器中存储元素的键可以重复。
multiset
定义在 头文件中,和 set 容器唯一的不同在于,multiset 容器中存储元素的值可以重复(一旦值重复,则意味着键也是重复的)。
map
#include
#include
