参考文献

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 <vector>
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.0

    int 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 <iostream>
    //需要引入 vector 头文件
    #include <vector>
    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 <iostream>
#include <map> //使用 map 容器,必须引入该头文件
#include <string>
using namespace std;
int main()
{
//创建一个空的 map 关联式容器,该容器中存储的键值对,其中键为 string 字符串,值也为 string 字符串类型
map<string, string> mymap;
//向 mymap 容器中添加数据
mymap["A"] = "1";
mymap["B"] = "2";
mymap["C"] = "3";
//使用 map 容器的迭代器,遍历 mymap 容器,并输出其中存储的各个键值对
for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); ++it) {
//输出各个元素中的键和值
cout << it->first << " => " << it->second << '\n';
}
return 0;
}