容器就是一些特定类型对象的集合,顺序容器(sequential container)的顺序与元素加入容器时的位置对应。
9.1 概述
sequential容器的类型:
1. vector 连续内存
2. deque 双端队列
3. list 快速添加,不能随机访问
4. forward_list
5. array 不能添加和删除
6. string 连续内存
选容器的基本原则
- 除非有更好的选择,一般使用vector
- 如果有很多小元素,空间的额外开销很重要不要使用list 或者forward list
- 随机访问 vector deque
- 头尾位置插入或者删除元素 deque
- 如果只有在输入时才在中间插入元素
- - -vector追加数据,再使用sort重排
- - -先使用list然后拷贝到vector
9.2 容器库概览
9.2.1 迭代器
forward_list不支持递减运算符–
begin 与end相等则范围为空
9.2.2 容器类型成员
每个容器都定义了多个类型,我们已经使用过size_type / iterator等,为了使用这些类型,我们必须显示的使用其类名:list<string>::iterator iter
9.2.3 begin end
begin和end各有两个同名成员用来被重载
当不需要写访问时,应该使用cbegin和cend。
9.2.4 容器的定义和初始化
- 将一个容器初始化为另外一个容器的拷贝,可以直接拷贝一个容器(容器类型相同时)也可以制定元素的范围(array除外)
- array具有固定的大小,大小是其的一个特性
- array初始化列表可以只初始化最开始几个元素
- 内置数组不可以进行拷贝或者对象赋值
9.2.5 赋值和swap
- array 赋值号两边对象必须具有相同的类型 :a2={0};//错误,如果a2是一个array。
- swap 比拷贝快得多,但是两个array会真正的交换元素,时间与数目成正比
- assign顺序容器
names.assign(oldstyle.cbing(),oldstyle.cend());
9.2.6 容器大小操作与关系运算符
关系运算符的两侧都必须是相同类型的容器
只有元素支持关系系运算符时才可以进行比较,如之前的sales_data类型并未定义<所以不能进行相应个关系运算
9.3 顺序容器操作
9.3.1 添加元素
push_back
emplace_back
push_front// vector 不支持push_front但是可以使用insert(begin(),);
emplace_front
insert(p,t)//返回迭代器
emplace(p,args)
insert(p,n,t)
insert(p.b,e)
insert(p,il)
向一个vector、string、deque,插入元素会使得所以指向容器的迭代器,引用,指针失效
//c是一个sales_data对象
c.emplace_back("09_90",25,1.3);//正确 直接输入三个参数
c.push_back("09_90",25,1.3);//错误 不能直接输入三个参数
c.push_back(Sales_data("09_90",25,1.3));//正确
9.3.2 访问元素
//注意:以下操作之前要确认c非空
//首元素
auto val=*c.begin(),val2=c.front();
//尾元素
auto last=c.end();
auto cal3=*(--last);//不能递减forward——list迭代器
auto val4=c.back();//forward_list不支持
//at和下标只适用于string vector deque array
c[n]
c.at(n)
9.3.3 删除元素
c.pop_back()
c.pop_front()
c.erase(p)
c.earse(b,e)
c.clear()
9.3.4 特殊的forward_list操作
forward_list是一个单项链表,没有简单的方法来获取一个元素的前驱,所以,这里定义了after来完成的
before_begin()
insert_after()
emplace_after()
emplace_after()
erase_after()
9.3.5 改变容器大小
resize不适用于array
c.resize(n,t)新添加的元素被初始化为t
9.3.6 容器操作可能使迭代器失效
如果是调用insert earse则会返回迭代器,可以用来更新
9.4 vector对象是如何增长的
shrik_to_fit
capacity()
reserve()
9.5 额外的string操作
9.5.1 构造string
string s (cp,n)
string s(s2,pos2)
string s (s2,pos2,len2)
s.substr(pos,n)
9.5.2 改变string的其他方法
insert earse assign都有了增加
另外又增加了append和replace函数
9.5.3 string 搜索
s.find();
s.rfind();
s.find_first_of();
s.find_last_of();
s.find_first_not_of();
s.find_last_not_of();
9.5.4 compare
s.compare()
9.5.5 数值转换
to_string()
stoi
stol
stoul
stoll
stoull
stof
stod
stold
9.6 容器适配器
下面这一段来自博客http://blog.csdn.net/thefutureisour/article/details/7751846
首先,我们要明白适配器是干什么的?其实就是一个接口转换装置,是得我们能用特定的方法去操作一些我们本来无法操作的东西。举一个例子,比如你的一个设备支持串口线,而你的电脑支持的是usb口,这时候,我们没有必要重新买一个支持usb的设备,只需要一根串口转usb口的小玩意,让你的设备能够连接到usb插口上,而它就是适配器。
那么C++中的容器适配器是干什么的呢?可以做一个类比,我们已有的容器(比如vector、list、deque)就是设备,这个设备支持的操作很多,比如插入,删除,迭代器访问等等。而我们希望这个容器表现出来的是栈的样子:先进后出,入栈出栈等等,此时,我们没有必要重新动手写一个新的数据结构,而是把原来的容器重新封装一下,改变它的接口,就能把它当做栈使用了。
标准库定义了三个顺序容器 stack queue 和 priority_queue.
stack 栈适配器 要求push_back pop_back back 可由除了array foorward_list之外的容器来构造 后进先出
queue 队列适配器 要求 back push_back front push_front 可由list或者deque构造 先进先出
priority_queue 要求 front push_back pop_back 随机访问 可由 vector 或者deque构造 最高优先级元素总是第一个出列