顺序容器
- vector
- 可变大小数组。支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢
- deque
- 双端队列。支持快速随机访问。在头尾位置插入/删除速度很快
- list
- 双向链表。只支持双向顺序访问。在list中任何位置进行插入/删除操作速度都很快
- forword_list
- 单向链表。只支持单向顺序访问。在链表任何位置进行插入/删除操作速度都很快
- array
- 固定数组大小。支持快速随机访问。不能添加或删除元素
- string
- 与vector相似的容器,但专门用于保存字符。随机访问快,在尾部插入/删除速度快
容器库概览
- 每个容器都定义在一个头文件中,文件名与类型名相同
对容器可以保存的元素类型的限制
//假定noDefault时一个没有默认构造函数的类型
vector<noDefault>v1(10,init);//提供了元素初始化器
//vector<noDefault>v2(10);
容器操作
类型别名
- iterator
- 容器类型的迭代器类型
- const_iterator
- 可以读取元素,但不能修改元素的迭代器类型
- size_type
- 无符号整数类型,足够保存此终容器类型最大可能容器的大小
- difference_type
- 带符号整数类型,足够保存两个迭代器之间的距离
- value_type
- 元素类型
- reference
- 元素的左值,与value_type&含义相同
- const_reference
- 元素的const左值类型
构造函数
- C c;
- 默认构造函数,构造空容器
- C c1(c2);
- 构造c2的拷贝c1
- C c(b,e);
- 构造c,将迭代器b和e指定的范围内的元素拷贝到c(array不支持)
- C c{a,b,c…};
- 列表初始化
赋值与swap
-
c1=c2
- 将c1中的元素替换成c2中元素
-
c1={a,b,c…}
- 将c1中的元素替换为列表中元素(不使用于array)
-
a.swap(b)
- 交换ab的元素
-
swap(a,b)
- 交换ab的元素
大小
- c.size()
- c中元素的数目(不支持forward_list)
- c.max_size()
- c可保存的最大元素数目
- c.empty()
- 若c中存储了元素,返回false,否则返回true
添加/删除元素(不适用于array)
-
不同容器中,这些操作接口不同
-
c.insert(args)
- 将args中的元素拷贝进c
-
c.emplace(inits)
- 使用inits构造c中的一个元素
-
c.erase(args)
- 删除args指定的元素
-
c.clear()
- 删除c中的所有元素,返回void
获取迭代器
- c.begin(),c.end()
- 返回指向c的首元素和尾元素之后位置的迭代器
- c.cbegin(),c.cend()
- 返回const_interator
反向容器的额外成员(不支持forward_list)
- reverse_iterator
- 按逆序寻址元素的迭代器
- const_reverse_iterator
- 不能修改元素的逆序迭代器
- c.rbegin(),c.rend()
- 返回指向c的尾元素和首元素之前位置的迭代器
- c.crbegin(),c.crend()
- 返回const_reverse_iterator
容器定义和初始化
-
每个容器类型都定义了一个默认构造函数。出array之外,其他容器的默认构造函数都会创建一个指定类型的空容器,且都可以接受指定容器大小和元素初始值的参
-
C c;
- 默认构造函数。如果C是一个array,则c中元素按默认方式初始化,否则为空
-
C c1(c2);
-
C c1=c2
- c1初始化为c2的拷贝。c1和c2必须是相同类型
-
C c{a,b,c…}
-
C c={a,b,c…}
- c舒适化为列表中元素的拷贝
-
C c(b,e)
- c初始化为迭代器b和e指定范围中的元素的拷贝
-
C seq(n)
- seq包含n个元素,这些元素进行了值初始化;此构造函数时explicit
-
C seq(n,t)
- seq包含n个初始化为值t的元素
-
只有顺序容器的构造函数才接受大小参数,关联容器不支持
赋值和swap
-
c1=c2
-
c={a,b,c…}
-
swap(c1,c2)
-
c1.swap(c2)
-
assign操作不使用与关联容器和array
-
seq.assgin(b,e);
- 将seq中的元素替换为迭代器b,e所表示范围中的元素。迭代器b和e不能指向seq中的元素
-
seq.assgin(il);
- 将seq中的元素替换为初始化列表il中的元素
-
seq.assign(n,t);
- 将seq中的元素替换为n个值为t的元素
-
assign操作用参数所指定的元素(的拷贝)替换左边容器中的所有元素,允许从一个不同但相容的类型赋值或从容器的一个子序列赋值
顺序容器操作
向顺序容器添加元素
- forward_list
- insert
- emplace
- c.push_back(t)
- c.emplace_back(args)
- 在c的尾部创建一个值为t或由args创建的元素,返回void
- c.push_front(t)
- c.emplace_front(t)
- 在c的头部创建一个值为t或由args创建的元素,返回void
- c.insert(p,t)
- c.emplace(p,args)
- 在迭代器p指向的元素之间创建一个值为t或由args创建的元素。返回指向新添加的元素的迭代器
- c.insert(p,n,t)
- 在迭代器p指向的元素之前插入n个值为t的元素,返回指向新添加的第一个元素的迭代器,若n为0则返回p
- c.insert(p,b,e)
- 将迭代器b和e指定的范围内的元素插入到迭代器p指向的元素之前。b和e不能指向c中的元素。返回指向新添加的第一个元素的迭代器。若范围为空,则返回p
- c.insert(p,il)
- il是一个花括号包围的元素值列表。将这些给定值插入到迭代器p指向的元素之前,返回指向新添加的第一个元素的迭代器,若列表为空,则返回p
- 向一个vector/string/deque插入元素都会使所有指向容器的迭代器、引用、指针失效
访问元素
- at和下标操作只适用于string\vector\deque\array
- back不适用于forward_list
- c.back()
- 返回c中尾元素的引用,若c为空,则函数行为未定义
- c.front()
- 返回c中首元素的引用,若c为空,则函数行为未定义
- c[n]
- 返回c中下标未n的元素的引用,n是一个无符号整数。若n>=c.size(),则函数行为为定义
- c.at(n)
- 返回下标为n的元素的引用,若下标越界,则抛出一out_of_range异常
删除元素
- forward_list不支持pop_back,vector/string不支持pop_front
- c.pop_back()
- 删除c中尾元素,若c为空,则函数行为未定义,函数返回void
- c.pop_front()
- 删除c中首元素
- c.erase§
- 删除迭代器p所指定的元素,返回一个指向被删元素之后元素的迭代器,若p指向尾元素,则返回尾后迭代器,若p是尾后迭代器,则函数行为未定义
- c.erase(b,e)
- 删除迭代器b和e所指定范围内的元素,返回一个指向最后一个被删元素之后元素的迭代器,若e本身就是一个尾后迭代器,则函数也返回尾喉迭代器
- c.clear()
- 删除c中所有元素,返回void
forward_list操作
- lst.before_begin()
- lst.cbefore_begin()
- 返回指向链表首元素之间不存在的元素的迭代器,此迭代器不能解引用。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.erase_after§
- lst.erase_after(b,e)
- 删除p指向的位置之后的元素,或删除从b之后知道(但不包含)e之间的元素,返回一个指向被删除元素之后元素怒的迭代器,若不存在这样的元素,则返回尾后迭代器,如果p指向lst的尾元素或者是一个尾后迭代器,则函数行为未定义
改变容器大小
- c.resize(n)
- 调整c的大小为n个元素,若n<c.size(),则多出的元素被丢弃,若必须添加新元素,对新元素进行值初始化
- c.resize(n,t)
- 调整c的大小为n个元素,任何新添加的元素都被初始化为t
vector对象是如何增长
管理容器的成员函数
- c.shrink_to_fit()
- 请将capacity()减少为与size()相同大小,只使用于vector、string、deque
- c.capacity()
- c可以保存的元素数量。只使用于vector、string
- c.reserve(n)
- 分配至少能够容纳n个元素的内存空间,只使用于vector、string
string操作
构造string的其他方法
- 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,即拷贝从pos开始的所有字符
改变string的其他方法
- s.insert(pos,args)
- 在pos之前插入args指定的字符。pos可以是一个下标或一个迭代器,接受下标的版本返回一个指向s的引用,接受迭代器的版本返回指向第一个插入字符的迭代器
- s.earse(pos,len)
- 删除从位置pos开始的len个字符,如果len被省略,则删除从pos开始直至s末尾的所有字符,返回一个指向s的引用
- s.append(args)
- s.replace(range,args)
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(agrs)
- 在s中查找第一个不在args中的字符
- s.find_last_not_of(args)
- 在s中查找最后一个不在args中的字符
- rfind为逆向搜索
compare函数
- s2
- 比较s和s2
- pos1,n1,s2
- 将s中从pos1开始的n1个字符与s2比较
- pos1,n1,s2,pos2,n2
- 将s中从pos1开始的n1个字符与s2中从pos2开始的n2个字符比较
- cp
- pos1,n1,cp
- 比较s与cp指向的以空字符结尾的字符数组
- pos1,n1,cp,n2
- 将s中从pos1开始的n1个字符与指针cp指向的地址开始的n2个字符进行比较
数值转换
- 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)
- stof(s,p)
- stod(s,p)
- stold(s,p)
容器适配器
- 使某种事物的行为看起来像另外一种事物一样
- satck/queue/priority_queue
定义一个适配器
- 每个适配器都定义两个构造函数
- 默认构造函数创建一个空对象
- 接受一个容器的构造函数拷贝该容器来初始化适配器
- stack/queue是基于queue实现
- priority_queue是基于vector实现
//deq是一个deque<int>
stack<int>stk(deq);//从deq拷贝元素到stk
栈适配器
stack<int>intStack;//空栈
//填满栈
for(size_t ix=0;ix!=10;++ix)
intStack.push(ix);
while(!intStack.empty()){
int valye = intStack.top();
intStack.pop;
}
s.pop();
//删除栈顶元素
s.push(item);
s.emplace(args);
//长江一个新元素压入栈顶
s.top();
//返回栈顶元素
队列适配器
q.pop();
//返回queue的首元素或priority_queue的最高优先级的元素,但不删除此元素
q.front();
//返回首元素或尾元素,但不删除此元素
q.back();
//只适用于queue
q.top();
//返回最高优先级元素,只适用于priority_queue
q.push(item);
q.emplace(args);
//在queue末尾或priority_queue中恰当的位置创建一个元素