STL容器备忘总结

Xilong Yang
2021-07-21

使用容器总有几个细节记不清,梳理一番以作备忘。

容器类型

顺序容器

顺序容器 描述
vector 可变大小数组,快速随机访问,快速尾部增删。
deque 双端队列,快速随机访问,快速头尾增删。
list 双向列表,双向顺序访问,快速任意增删。
forward_list 单向列表,单向顺序访问,快速任意增删。
array 固定大小数组,快速随机访问,不可增删。
string 与vector性质相似,专门保存字符。
顺序容器适配器 描述
stack
queue 队列
priority_queue 优先队列

关联容器

关联容器 描述
map 关联数组,保存key-value对。
unordered_map map的无序版本。
set 只保存key的容器。
unordered_set set的无序版本。
multimap key可重复出现的map。
unordered_multimap multimap的无序版本。
multiset key可重复出现的set。
unordered_multiset multiset的无序版本。

有序关联容器要求key值类型必顺定义<运算符。无序关联容器则要求key值定义==运算符。

容器操作

通用操作

类型别名

iterator: 容器的迭代器类型。

const_iterator: 迭代器的只读版本。

size_type: 无符号整数类型,保存最大容器大小。

differenct_type: 带符号整数类型,保存两个迭代器间的距离。

value_type: 元素类型。

reference: 元素的左值类型,含义为value_type&。

const_reference: 元素的const左值类型,含义为const value_type&。

构造函数

C c;:默认构造函数,构造一个空容器。

C c1(c2):构造c2的拷贝c1。

C c(b, e):构造c并将迭代器b和e之间的元素拷贝到c。

C c{a, b, c, d, e...}:列表初始化c。

赋值与swap

c1 = c2:将c1中的元素替换为c2中的元素。

c = {a, b, c, d...}:将c中的元素替换为列表中的元素(array不可用)。

a.swap(b), swap(a, b):交换a,b中的元素。

大小

c.size():c中元素数目。

c.max_size():c最大可保存元素数目。

c.empty:c是否为空。

增删元素(array不可用)

c.insert(args):将args中的元素拷贝进c。

c.emplace(inits):使用inits构造c中的一个元素。inits必需与元素的构造函数匹配。

c.erase(args):删除c中的指定元素。

c.clear():删除c中所有元素,返回void。

关系运算符

==!=:所有容器都支持。

<<=>>=:除无序关联容器外都支持。

获取迭代器

c.begin()c.end():返回首迭代器和尾后迭代器。

c.cbegin()c.cend():返回const迭代器。

反向迭代器(不支持forward_list)

reverse_iterator:按逆序寻址元素的迭代器

const_reverse_iterator:反向迭代器的只读版本。

c.rbegin()c.rend():返回尾迭代器和首前迭代器。

c.crbegin()c.crend():返回const反向迭代器。

顺序容器操作

总是可以使用两个迭代器的范围表示多个已存在元素,用(n, t)或{a, b, c…}表示多个新元素。将这三种表示方法称为range

构造函数

C seq(n):一个包含n个元素的顺序容器。

C seq(range):一个元素为range的顺序容器。

赋值

seq.assign(range):将seq中元素替换为迭代器range中的元素,b的e不可指向seq中的元素。

关系运算符

两个大小相等且对位元素相等的顺序容器相等。

顺序容器a是另一个顺序容器b的前缀子序列时,a < b。

否则,以两容器中第一对不相等的元素的大小关系作为结果。

增删元素(array不支持)

c.push_back(t)c.emplace_back(inits):在尾部创建一个元素。

c.push_front(t)c.emplace_front(inits):在首部创建一个元素。

c.insert(p, t)c.emplace(p, inits):在迭代器p位置之前添加一个元素,返回新元素的迭代器。

c.insert(p, range):在p之前添加n个值为t的元素。返回第一个新元素的迭代器。

任何添加操作都会导致指向容器内元素的迭代器、指针和引用失效。

c.pop_back():删除c的尾元素,c为空时UB。

c.pop_front():删除c的首元素,c为空时UB。

c.erase(p):删除迭代器p指向的元素,返回下一个元素的迭代器。p为尾后迭代器时UB。

c.erase(b, e):删除迭代器b, e范围内的所有元素,返回下一个元素的迭代器。

c.clear():删除所有元素,返回void。

删除deque中除首尾元素的任何元素会导致迭代器、指针和引用失效。

删除vector或string中的元素会导致删除点之后的迭代器、指针和引用失效。

访问元素

c.back():返回c中尾元素的引用。c为空时UB。

c.front():返回c中首元素的引用。c为空时UB。

c[n]c.at(n):返回下标为n的元素的引用。[下标]越界UB。at(下标)越界抛出一个out_of_range异常。

改变容器大小

c.resize(n):将容器大小调整为n,若缩小则丢弃多余元素,增大则添加新元素。

c.resize(n, t):若增大则添加值为t的新元素。

forward_list特有操作

lst.before_begin():返回首前迭代器,不可解引用。

lst.cbefore_begin():返回首前迭代器的只读版本。

lst_insert_after(p, args)emplace_after(p, inits):在p后添加元素,参数形式与通用的insert相同。

lst_erase_after(p)lst_erase_after(p, e):删除p之后的一个或一段元素,返回下一个位置。

缓存操作

c.shrink_to_fit():将实际内存占用减少为与size()相同。只适用于vector,string和deque

c.capacity():已分配的实际内存可以保存多少元素。只适用于vector和string。

c.reserve(n):分配至少能容纳n个元素的空间。只适用于vector和string。

string特有操作

截取

string s(cp, n):cp指向数组中前n个字符。

string s(s2, pos, len = 0):字符串s2从下标pos开始的len个字符。下标越界则UB。

s.sub_str(pos = 0, n = s.size() - pos):返回s从下标pos开始的n的字符的拷贝。

搜索

string提供了六个不同的搜索函数,每个函数又有4个重载版本。它们成功时返回匹配位置的下标,失败则返回string::npos。返回数类型都是string::size_type,是无符号整数类型。

s.find(args):args第一次出现的位置。

s.rfind(args):args最后一次出现的位置。

s.find_first_of(args):args中任一字符第一次出现的位置。

s.find_last_of(args):args中任一字符最后一次出现的位置。

s.find_first_not_of(args):第一次出现不属于args中的字符的位置。

s.find_last_not_of(args):最后一次出现不属于args中的字符的位置。

args为以下四种形式之一:

c, pos:从pos处开始查找字符c,pos默认为0。

str, pos:从pos处开始查找字符串str,pos默认为0。

cp, pos:从pos处开始查找C风格字符串指针cp,pos默认为0。

cp, pos, n:从pos开始查找指针cp指向的数组的前n个字符。pos和n皆无默认值。

匹配

s.compare(args):跟据比较结果等于,小于或大于args,返回0,负数或正数。

args为以下形式之一:

s2:与字符串s2比较。

pos1, n1, s2:从pos1开始的n1个字符与s2比较。

pos1, n1, s2, pos2, n2:从pos1开始的n1人字符与s2中从pos2开始的n2的字符比较。

cp:与C风格字符串cp比较。

pos1, n1, cp:从pos1开始的n1个字符与cp比较。

pos1, n1, cp, n2:从pos1开始的n1个字符与从cp开始的n2个字符比较。

数值转换

to_string(val):返回val的string表示。

sto{type}(s, p, b):返回s起始的子串的数值,由type指定返回值类型。b表示进制,默认为10。p是size_t指针,用来保存第一个非数值字符的下标,默认为0,即不保存下标。type可以为:i (int)、l (long)、ul (unsigned long)、ll (long long)、ull (unsigned long long)。

sto{type}(s, p):基本同上,返回浮点数,不能指定进制。type可以为:f (float)、d (double)、ld (long double)。

容器适配器操作

container_type:实现适配器的底层容器类型。

关联容器操作

key_type:关键字类型。

mapped_type:映射类型,仅适用于map。

value_type:值类型,对于set与key_type等效,对于map等于pair<const key_type, mapped_type>

遍历

可以通过begin()end()获取对应的迭代器从而实现遍历。

插入元素

c.insert(v):对于map和set,key值重复的插入会失败,返回一个bool表示是否成功。而multimap和multiset可以插入key值重复的元素,返回指向该元素的迭代器。

c.emplace(args):行为同上,使用args构建元素。

c.insert(b, e):插入迭代器范围内的元素。

c.insert(li):插入初始化列表中的元素。

c.insert(p, v):从迭代器位置开始插入元素。

c.emplace(p, args):同上。

删除元素

c.erase(k):删除所有key值为k的元素。

c.erase(p):删除迭代器指向的元素。

c.erase(b, e):删除迭代器范围内的元素。

map的下标操作

map[key]:取得key对应的value,如果key不存在则创建新元素。

访问元素

c.find(k):返回指向第一个key值为k的元素的迭代器。

c.count(k):返回key值为k的元素的数量。

c.lower_bound(k):返回指向第一个key值不小于k的元素的迭代器。

c.upper_bound(k):返回指向第一个key值大于k的元素的迭代器。

c.equal_range(k):返回一个迭代器pair,表示关键字等于k的元素的范围。

无序容器

无序容器unorderd_mapunordered_set,在存储上组织为一组桶,每个桶保存0或多个元素。使用hash函数将元素映射到桶。因此,无序元素的性能依赖于hash函数的质量和桶的数量与大小。

适用于有序容器的操作也适用于无序容器,此外无序容器提供了一组管理桶的函数:

c.bucket_count():正在使用的桶的数目。

c.max_bucket_count():容器能容纳的最多的桶的数目。

c.bucket_size(n):第n个桶中有多少元素。

c.bucket(k):关键字为k的元素在哪个桶中。

local_iterator:用来访问桶中元素的迭代器类型。

const_local_iterator:迭代器的const版本。

c.begin(n)c.end(n)c.cbegin(n)c.cend(n):桶n的对应迭代器。

c.load_factor():每个桶的平均元素数量,返回float值。

c.max_load_factor():c试图维护的平均桶大小,返回float值。c会在需要时添加新的桶,使load_factor <= max_load_factor。

c.rehash(n):重组存储,使bucket_count >= n且bucket_count > size / max_load_factor。

c.reserve(n):重组存储,使c可以保存n个元素而不用rehash。

// 无序容器的使用
T1 hash(args);
bool equal(T2 a, T2 b);
// 由于模版参数接受的是类型,使用decltype取得函数的类型。
unordered_map<T2, decltype(hash)*, decltype(equal)*> foo;
© 2019- Xilong Yang | CC BY-NC 4.0 | Powered by LaTeX.css, Prism, MathJax