顺序容器
一、梳理
1. 容器
- 一些特定类型对象的集合
2. 顺序容器如何存储值
- “顺序”不依赖于元素的值,而是与元素加入容器时的位置相对应
3. 有哪些顺序容器
顺序容器 | 类型 | 说明 |
vector | 可变大小数组 | 支持快速随机访问,在尾部插入/删除元素很快 |
deque | 双端队列 | 支持快速随机访问,在头尾插入/删除元素很快 |
list | 双向链表 | 支持双向顺序访问,在任意位置插入/删除都快 |
forward_list | 单向链表 | 支持单向顺序访问,在任意位置插入/删除都快 |
array | 固定大小数组 | 支持快速随机访问,不能添加/删除元素 |
string | 存字符的容器 | 支持快速随机访问,在尾部插入/删除字符很快 |
4. 如何选择合适的容器
- list/forward_list:需要在容器的中间插入或删除元素
- deque:需要在头尾位置插入或删除元素
- vector/deque:需要随机访问元素
- list+vector:既需要在输入元素时向容器中间插入元素,插入完成后又需要随机访问元素,我们可以在输入时使用list,然后将list的元素拷贝到vector中
5. 迭代器范围
- 由一对迭代器表示,它们标记了容器中元素的一个范围,元素范围常用左闭合区间表示:[begin, end)
二、容器成员
1. 自定义类型
类型名称 | 说明 |
iterator const_iterator |
此容器的迭代器类型 可以读取元素,但不能修改元素的迭代器类型 |
size_type | 无符号整数类型,足够保存此种容器类型最大可能容器的大小 |
difference_type | 带符号整数类型,足够保存两个迭代器之间的距离 |
value_type | 元素类型 |
reference const_reference |
元素的左值类型,与value_type&含义相同 元素的const左值类型,即const value_type& |
reverse_iterator const_reverse_iterator |
按逆序寻址元素的迭代器 不能修改元素的逆序迭代器 |
注:为了使用这些类型,我们必须显式使用其类名,如“list<int>::size_type a;”表示使用list<int>类定义的size_type成员。
2. 容器操作
操作 | 说明 |
C c(b, e) | c初始化为迭代器b和e指定的范围内的元素的拷贝 |
C c1(c2) | c1初始化为c2的拷贝 |
C c{a, b, c...} C c = {a, b, c...} |
c初始化为初始化列表中元素的拷贝 |
c1 = c2 | 将c1中的元素替换为c2中的元素 |
c1 = {a, b, c...} | 将c1中的元素替换为列表中的元素(不适用于array) |
c.begin() c.end |
返回指向c的首元素位置的迭代器 返回指向c的尾元素之后位置的迭代器 |
c.rbegin c.rend() |
返回指向c的尾元素位置的迭代器 返回指向c的首元素之前位置的迭代器 |
a.swap(b) swap(a, b) |
交换a和b的元素 |
c.push_front(t) c.emplace_front(args) |
在c的头部创建一个值为t或由args创建的元素,返回void vector和string不支持这两个操作 |
c.pop_back() c.pop_front() |
删除c中尾元素,forward_list不支持 删除c中首元素,vector和sring不支持 |
c.insert(p, t) c.emplace(p, args) c.insert(p, n, t) c.insert(p, b, e) c.insert(il) |
(插入一个元素)在迭代器p指向的元素之前创建一个值为t或由args创建的元素,返回指向新添加的元素的迭代器 在迭代器p指向的元素之前插入n个值为t的元素,返回指向新添加的第一个元素的迭代器(n为0,则返回p) 将迭代器b和e指定的范围内的元素插入到迭代器p指向的元素之前,返回指向新添加的第一个元素的迭代器(若范围为空,则返回p) 与上一个类似,只是将添加的元素变为一个由花括号包围的元素值列表il中的元素 |
c.erase(p) c.erase(b, e) |
删除迭代器p所指定的元素,返回一个指向被删元素之后元素的迭代器,若p指向尾元素,则返回尾后迭代器,若p是尾后迭代器,则函数未定义 删除迭代器b和e所指定范围内的元素,返回一个指向最后一个被删元素之后的迭代器,若e本身就是尾后迭代器,则函数也返回尾后迭代器 |
c.clear() |
删除c中的所有元素 |
c.front() c.back() |
返回c中首元素的引用,forward_list不支持 返回c中尾元素的引用 |
c[n] c.at(n) |
返回c中下标为n的元素的引用(只适用于string、vector、deque、array) |
c.size() c.max_size() c.resize(n) c.resize(n, t)
|
返回容器中元素的数目,forward_list不支持 返回一个大于或等于该类型容器所能容纳的最大元素数的值 调整c的大小为n个元素(若需要添加新元素,则对新元素进行值初始化<所以若是类类型的元素,则其必须提供默认构造函数>) 调整c的大小为n个元素(任何新添加的元素都初始化为值t) |
c.capcity() c.reserve(n) c.shrink_to_fit() |
不重新分配内存空间的话,c可以保存多少元素(一般大于等于size) 分配能容纳n个元素的内存空间(并不改变容器中元素的数量,resize则改变容器中元素的数量,它只是给出给c预先分配多大的内存空间) 将capcity()减少为与size()相同大小 |
3. 顺序容器特有的操作
操作 | 说明 |
C c(n) C c(n, t) |
c包含n个元素,这些元素进行了值初始化 c包含了n个初始化为值t的元素 |
c.assign(b, e) c.assign(il) c.assign(n, t) |
将c中的元素替换为迭代器b和e所表示的范围中的元素 将c中的元素替换为初始化列表il中的元素 将c中的元素替换为n个值为t的元素 |
4. string特有的操作
- const char *cp = "You shule be my lady,kzw";
操作 | 说明 |
string s(cp, n) | s是cp指向的数组中前n个字符的拷贝,此数组至少应该包含n个字符 |
string s(s2,pos2) | s是string s2从下标pos2开始的字符的拷贝 |
string s(s2, pos2, len2) | s是string s2从下标pos2开始len2个字符的拷贝 |
s.substr(pos, n) | 返回一个string,包含s中从pos开始的n个字符的拷贝(pos的默认值为0,n的默认值为s.size()-pos) |
s.assign(cp, 7) | 用从cp指向的地址开始的7个字符来替换s的内容 |
s.insert(s.size(), 5, '!') s.insert(s.size(), "!!!") s.insert(s.size(), cp+7) s.insert(0, s2) s.insert(0, s2, 0, s2.size()) |
在s末尾插入5个感叹号(s.size()是s的尾元素的后一位置) 在s末尾插入3个感叹号 将从cp的第七个字符到结尾的字符序列插入到s的末尾 在s中位置0之前插入s2的拷贝 在s[0]之前插入s2中的s2[0]开始的s2.size()个字符 |
s.erase(s.size() - 5, 5) s.erase(11, 3) |
删除s的最后5个字符 从位置11开始,删除3个字符 |
s.replace(11, 3, "!!!!") s.replace(b, e, "!!!!") |
从位置11开始,删除3个字符并插入4个感叹号 删除迭代器表示范围,并插入4个感叹号 |
s.append("kzw") | 在s的末尾插入"kzw" |
s.find(c, pos) s.find(s2, pos) |
从s中位置pos开始查找字符c,pos默认值为0 从s中位置pos开始查找字符串s2,pos默认值为0 |
s.rfind(args) s.find_first_of(s2) s.find_first_not_of(s2) |
查找s中args最后一次出现的位置 返回s2中任意一个字符在s中第一次出现的位置 返回s中第一个s2没有的字符的位置 |
5. 容器适配器
- stack、queue、priority_queue