1:顺序容器类型
vector | 可变大小数组。支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢 |
---|---|
deque | 双端队列。支持快速随机访问。在头尾位置插入/删除速度很快 |
list | 双向链表。只支持双向顺序访问。在list中任何位置进行插入/删除操作速度都很快 |
forward_list | 单向链表。只支持单向顺序访问。在链表任何位置进行插入/删除操作速度都很快 |
array | 固定大小数组。支持快速随机访问。不能添加或删除元素 |
string | 与vector相似的容器,但专门用于保存字符。随机访问快。在尾部插入/删除速度快 |
2:容器操作
类型别名
iterator | 此容器类型的迭代器类型 |
---|---|
const_iterator | 可以读取元素,但不能修改元素的迭代器类型 |
size_type | 无符号整数类型,足够保存此种容器类型最大可能容器的大小 |
different_type | 带符号整数类型,足够保存两个迭代器之间的距离 |
c.begin(),c.end() | 返回指向c的首元素和尾元素之后位置的迭代器 |
c.cbegin(),c.cend() | 返回const_iterator |
反向容器的成员
reverse_iterator | 按逆序寻址元素的迭代器 |
---|---|
const_reverse_iterator | 不能修改元素的逆序迭代器 |
c.rbegin(),c.rend() | 返回指向c的尾元素和首元素之前位置的迭代器 |
c.crbegin(),c.crend() | 返回const_reverse_iterator |
容器定义和初始化
C c | 默认构造函数。如果C是一个array,则c中元素按默认方式初始化,否则c为空 |
---|---|
C c1(c2)和C c1 = c2 | c1初始化为c2的拷贝。c1和c2必须是相同类型。 |
C c{a,b,c…}和C c = {a,b,c..} | c初始化为初始化列表中元素的拷贝。列表中元素的类型必须与C的元素类型相容。对于array类型,列表中元素数目必须等于或少于array的大小,任何遗漏的元素都进行值初始化。 |
C c(b,e) | c初始化为迭代器b和e指定范围中的元素的拷贝。当传递一个迭代器范围进行拷贝时,就不要求容器类型相同了,并且元素类型能够转换为要初始化的容器的元素类型即可 |
C seq(n) | seq包含n个元素,这些元素进行了值初始化;此构造函数是explicit的 |
C seq(n,t) | seq包含n个初始化为值t的元素 |
seq.assign(b,e) | 将seq中的元素替换为迭代器b和e所表示范围中的元素。迭代器b和e不能指向seq中的元素。另有seq.assign(il)及seq.assign(n,t) |
3:顺序容器添加元素和删除元素
向容器添加元素之后:
⑴.如果容器是vector或string,且存储空间被重新分配,则指向容器的迭代器、指针和引用都会失效。如果存储空间未被重新分配,指向插入位置之前的元素的迭代器、指针和引用仍有效,但指向插入位置之后元素的迭代器、指针和引用将会失效。
⑵.对于deque,插入到除首尾位置之外的任何位置都会导致迭代器、指针和引用失效。如果在首尾位置添加元素,迭代器会失效,但指向存在的元素的引用和指针不会失效。
⑶.对于list和forward_list,指向容器的迭代器(包括尾后迭代器和首前迭代器)、指针和引用仍然有效。
当我们删除一个元素后:
⑴.对于list和forward_list,指向容器其他位置的迭代器(包括尾后迭代器和首前迭代器)、指针和引用仍然有效。
⑵.对于deque,如果在首尾之外的任何位置删除元素,那么指向被删除元素之外其他元素的迭代器、引用或指针也会失效。如果是删除deque的尾元素,则尾后迭代器也会失效,但其他迭代器、引用和指针不受影响;如果是删除首元素,这些也不会受影响。
⑶.对于vector和string,指向被删元素之前元素的迭代器、引用和指针仍然有效。
注:当我们删除元素时,尾后迭代器总是会失效。
4:顺序容器中添加元素
c.push_back(t) | 在容器 c 的尾部添加值为 t 的元素。返回 void 类型,forward_list不支持 |
---|---|
c.push_front(t) | 在容器 c 的前端添加值为 t 的元素。返回 void 类型,vector和string不支持 |
c.insert(p,t) | 在迭代器 p 所指向的元素前面插入值为 t 的新元素。返回指向新添加元素的迭代器。forward_list有自己版本的insert |
c.insert(p,n,t) | 在迭代器 p 所指向的元素前面插入 n 个值为 t 的新元素。返回 void 类型 |
c.insert(p,b,e) | 在迭代器 p 所指向的元素前面插入由迭代器 b 和 e 标记的范围内的元素。返回 void 类型 |
5:顺序容器的大小操作
c.size() | 返回容器 c 中的元素个数。返回类型为 c::size_type |
---|---|
c.max_size() | 返回容器 c 可容纳的最多元素个数,返回类型为 c::size_type |
c.empty() | 返回标记容器大小是否为 0 的布尔值 |
c.resize(n) | 调整容器 c 的长度大小,使其能容纳 n 个元素,如果 n < c.size(),则删除多出来的元素;否则,添加采用值初始化的新元素 |
c.resize(n,t) | 调整容器 c 的长度大小,使其能容纳 n 个元素。所有新添加的元素值都为 t |
6:访问顺序容器内元素的操作
c.back() | 返回容器 c 的最后一个元素的引用。如果 c 为空,则该操作未定义,不适用于forward_list |
---|---|
c.front() | 返回容器 c 的第一个元素的引用。如果 c 为空,则该操作未定义 |
c[n] | 返回下标为 n 的元素的引用 如果 n <0 或 n >= c.size(),则该操作未定义不适用于list和forward_list |
c.at(n) | 返回下标为 n 的元素的引用。如果下标越界,则该操作未定义,不适用与list和forward_list |
7:顺序容器中元素的删除
forward_list有自己的删除操作。
c.pop_back() | 删除容器c的最后元素。返回void类型。如果c为空容器,则该函数未定义,forward_list不支持该操作 |
---|---|
c.pop_front() | 删除容器c的第一个元素。返回void类型,如果c为空容器,则该函数未定义,不适用于vector和string |
c.erase(p) | 删除迭代器p所指向的元素。返回一个迭代器,它指向被删除元素后面的元素。如果p指向容器内的最后一个元素,则返回的迭代器指向容器的超出末端的下一位置。如果p本身就是指向超出末端的下一个位置的迭代器,则该函数未定义 |
c.erase(b, e) | 删除迭代器b和e所标记范围内的元素。返回一个迭代器,它指向被删除元素段后面的元素。如果e本身就是指向超出末端的下一位置,则返回的迭代器也指向超出末端的下一个位置 |
c.clear() | 删除容器内所有的元素。返回void类型 |
8:forward_list所支持的操作
由于forward_list是单向链表,当对单向链表添加或删除一个元素时,删除或添加的元素之前的那个元素的后继会发生改变,为了添加或删除一个元素,我们需要访问其前驱,以便改变前驱的链接。为支持这写操作,forward_list定义了before_begin,它返回一个首前迭代器。这个迭代器允许我们在链表首元素之前并不存在的元素“之后”添加或删除元素。
lst.before_begin() | 返回指向链表首元素之前不存在的元素的迭代器。此迭代器不能解引用 |
---|---|
lst.cbefore_begin() | 返回一个const_iterator |
lst.insert_after(p,t)/ lst.insert_after(p,n,t)/ lst.insert_after(p,b,e)/lst.insert_after(p,il) | 在迭代器p之后的位置插入元素,t是一个对象,n是数量,b和e是表示范围的一对迭代器(b和e不能指向lst内), il是一个花括号列表。返回一个指向最后一的个插入元素的迭代器。如果范围为空,则返回p。若p为尾后迭代器,则函数行为未定义 |
emplace_after(p,args) | 使用args在p指定的位置之后创建一个元素。返回一个指向这个新元素的迭代器。若p为尾后迭代器,则函数行为未定义 |
lst.earse_after(p)/lst.earse_after(b,e) | 删除p指向的位置之后的元素,或删除从b之后直到(但不包含)e之间的元素。返回一个指向被删元素之后元素的迭代器,若不存在这样的元素,则返回尾后迭代器。如果p指向lst的尾元素或者是一个尾后迭代器,则函数行为未定义 |
9:vector是如何增长的
shrink_to_fit只使用于vector、string和deque
capacity和reserve只适用于vector和string
c.shrink_to_fit() | 请将capacity()减少为与size()相同大小 |
---|---|
c.capacity() | 不重新分配内存空间的话,c可以保存多少元素 |
c.reserve(n) | 分配至少能容纳n个元素的内存空间 |
当添加的数超出了vector原本分配的最大容量,vector的实现采用的策略是在每次需要分配新内存空间时将当前容量翻倍。
10:额外的string操作
1)构造string的其他方法
string s(cp,n) | s是cp指向的数组中前n个字符的拷贝。此数组至少应该包含n个字符 |
---|---|
string s(s2,pos2) | s是string s2从下标pos2开始的字符的拷贝。若pos2>s2.size(),构造函数的行为未定义 |
string s(s2,pos2,len2) | s是string s2从下标pos2开始len2个字符的拷贝。若pos2>s2.size(),构造函数的行为未定义。不管len2的值是多少,构造函数至多拷贝s2.size()-pos2个字符 |
2)子字符串操作
s.substr(pos,n):返回一个string,包含s中从pos开始的n个字符的拷贝。pos的默认值为0。n的默认值为s.size()-pos,即拷贝从pos开始的所有字符。
3)修改string的操作
s.insert(pos,args) | 在pos之前插入args指定的字符。pos可以是一个下标或一个迭代器。接受下标的版本返回一个指向s的引用;接受迭代器的版本返回指向第一个插入字符的迭代器 |
---|---|
s.earse(pos,len) | 删除从位置pos开始的len个字符。如果len被省略,则删除从pos开始直至s末尾的所有字符。返回一个指向s的引用 |
s.assign(args) | 将s中的字符替换为args指定的字符。返回一个指向s的引用 |
s.append(args) | 将args追加到s。返回一个指向s的引用 |
s.replace(range,args) | 删除s中范围range内的字符,替换为args指定的字符。range或者是一个下标和一个长度,或者是一对指向s的迭代器。返回一个指向s的引用 |
4)string搜索操作
s.find(args) | 查找s中args第一次出现的位置 |
---|---|
s.rfind(args) | 查找s中args最后一次出现的位置 |
s.find_first_of(args) | 在s中查找args中任何一个字符第一次出现的位置 |
s.find_last_of(args) | 在s中查找args中任何一个字符最后第一次出现的位置 |
s.find_first_not_of(args) | 在s中查找第一个不在args中的字符 |
s.find_last_not_of(args) | 在s中查找最后一个不在args中的字符 |
对于以上搜索函数,每个函数都有4个重载版本。
args是以下形式之一:
c,pos | 从s中位置pos开始查找字符c。pos默认为0 |
---|---|
s2,pos | 从s中位置pos开始查找字符串s2。pos默认为0 |
cp,pos | 从s中位置pos开始查找指针cp指向的以空字符结尾的C风格字符串。pos默认为0 |
cp,pos,n | 从s中位置pos开始查找指针cp指向的数组的前n个字符。pos和n无默认值 |
每个搜索操作都会返回一个string::size_type值,表示匹配发生位置的下标。
如果搜索失败,则返回一个名为string::npos的static成员。
标准库将npos定义成一个const string::size_type类型,并初始化为-1。
string搜索函数返回string::size_type值,该类型时一个unsigned类型,因此我们应该尽量不要使用带符号类型来保存这些返回值
5)字符串比较函数
s.compare(args)
args形式
s2 | 比较s和s2 |
---|---|
pos1,n1,s2 | 将s中从pos1开始的n1个字符与s2比较 |
pos1,n1,s2,pos2,n2 | 将s中从pos1开始的n1个字符与s2中从pos2开始的n2个字符进行比较 |
cp | 比较s与cp指向的以空字符结尾的字符数组 |
pos1,n1,cp | 将s中从pos1开始的n1个字符与cp指向的以空字符结尾的字符数组进行比较 |
pos1,n1,cp,n2 | 将s中从pos1开始的n1个字符与cp指向的地址开始的n2个字符进行比较 |
6)string和数值之间的转换
string参数中第一个非空白符必须是符号(+或-)或数字。它可以以0x或0X开头来表示十六进制数。对那些将字符串转换为浮点值的函数,string参数也可以以小数点开头,并可有包含e或E来表示指数部分。对于那些将字符串转换为整型值的函数,根据基数不同,string参数可以包含字母字符,对应大于数字9的数
如果string不能转换为一个数值,这些函数抛出一个invalid_argument异常。如果转换得到的数值无法用任何类型表示,则抛出一个out_of_range异常
to_string(val) | 一组重载函数,返回数值val的string表示。val可以是任何算术类型。对每个浮点类型和int或更大的整型,都有相应版本的to_string。与往常一样,小整型会被提升 |
---|---|
stoi(s,p,b) / stol(s,p,b)/ stoul(s,p,b) /stoll(s,p,b)/stoull(s,p,b) | 返回s的起始子串(表示整数内容)的数值,返回值类型分别是int,long,unsigned long,long long,unsigned long long。b表示转换所用的基数,默认值是10。p是size_t指针,用来保存s中第一个非数值字符下标,p默认为0,即函数不保存下标 |
stof(s,p) /stod(s,p) / stold(s,p) | 返回s的起始子串(表示浮点数内容)的数值,返回值类型分别是float,double或long double。参数p的作用于整数转换函数中一样 |
11:容器适配器
STL提供了三个容器适配器:queue、priority_queue、stack。这些适配器都是包装了vector、list、deque中某个顺序容器的包装器。注意:适配器没有提供迭代器,也不能同时插入或删除多个元素。
1)stack
#include <stack>
template < typename T, typename Container=deque > class stack;
//可以使用三个标准顺序容器vecotr、deque(默认)、list中的任何一个作为stack的底层模型。
bool stack<T>::empty() //判断堆栈是否为空
void stack<T>::pop() //弹出栈顶数据
stack<T>::push(T x) //压入一个数据
stack<T>::size_type stack<T>::size() //返回堆栈长度
T stack<T>::top() //得到栈顶数据
代码示例:
stack<int> intDequeStack;
stack<int,vector<int>> intVectorStack;//可用来声明一个二维数组
stack<int,list<int>> intListStack;
2)queue
#include <queue>
template<typename T, typename Container = deque<T> > class queue;
//第一个参数指定要在queue中存储的类型,第二个参数规定queue适配的底层容器,可供选择的容器只有deque和list。对大多数用途使用默认的deque。因为queue支持front和back操作,所以不能用vector作为底层适配器
queue<T>::push(T x)
void queue<T>::pop()
T queue<T>::back()//返回队尾元素
T queue<T>::front()//queue没有top操作,只能用front替代。返回队首元素
queue<T>::size_type
queue<T>::size()
bool queue<T>::empty()
代码示例:
queue<int> intDequeQueue;
queue<int,list<int>> intListQueue;
3)priority_queue
#include <queue>
template <typename T, typename Container = vector<T>, typename Compare = less<T> > class priority_queue;
//priority_queue也是一个队列,其元素按有序顺序排列。其不采用严格的FIFO顺序,给定时刻位于队头的元素正是有最高优先级的元素。如果两个元素有相同的优先级,那么它们在队列中的顺序就遵循FIFO语义。默认适配的底层容器是vector,也可以使用deque,list不能用,因为priority_queue要求能对元素随机访问以便进行排序。
priority_queue<T>::push(T x)
void priority_queue<T>::pop()
T priority_queue<T>::top()//返回优先级最高的元素
priority_queue<T>::size_type
priority_queue<T>::size()
bool priority_queue<T>::empty()
代码示例:
priority_queue< int, vector<int>, greater<int> >
priority_queue< int, list<int>, greater<int> >
greater函数定义在头文件functional中