第9章 顺序容器

9.1 顺序容器概述

名称
大小
随机访问
特点
迭代器操作+n,-n、-和关系运算
默认构造函数
是否支持列表初始化
是否支持assign
是否支持花括号赋值
是否支持大小操作,max_size,empty,size
vector
可变
支持
尾部之外插入慢
都支持
支持
支持
支持
支持
都支持
deque
可变
支持
头尾插入快
都支持
支持
支持
支持
支持
都支持
list
可变
双向顺序
任意位置插入快
不支持
支持
支持
支持
支持
不支持size
forward_list
可变
单向顺序
任意位置插入快
不支持
支持
支持
支持
支持
都支持
array
固定
支持
不能插入删除
都支持
不支持
需要指定大小
不支持
不支持
都支持
string
可变
支持
尾部之外插入慢
都支持
支持
支持
支持
支持
都支持
确定使用哪种顺序容器
1.最好使用vector
2.如果额外开销很重,不要用list或forward_list
3.如果需要随机访问用vector和deque
4.在头尾插入,不在中间插入用deque

9.2容器库概览

每个容器都定义在一个头文件中,文件名与类型名相同。

9.2.1迭代器

一个迭代器范围为左闭合区间
1.如果begin和end相等则范围为空。
2.如果begin和end不等,则只要包含一个元素。
3.可以对begin递增若干次,使得begin==end

9.2.2 容器类型成员

size_type 保存此容器类型大小
difference_type 有符号整数,足够保存两个迭代器之间距离
value_type 元素类型
reference   元素左值类型,与value_type&含义相同
const_reference 元素的const左值类型

9.2.3 begin和end成员

begin和end生成指向容器第一个元素和尾元素之后位置的迭代器。

9.2.4容器定义和初始化

除array外其他容器的默认构造函数都会创建一个指定类型的空容器。
将一个容器初始化为另外一个容器的拷贝
为创建一个容器为另外一个容器的拷贝,两个容器的类型和元素类型必须匹配。当传递迭代器参数来拷贝一个范围时,就不要求容器类型是相同的了。而且新容器和原容器类型可以不同,只要能将拷贝的元素转换。
list<string> authors = {"Millon","Shakespeare","au"};
vector<const char*> article = {"a","an","the"};
list<string> list2(authors); //正确,类型匹配
deque<string> authList(authors);//错误,容器类型不匹配
vector<string> words(article);//错误:容器类型必须匹配
//正确可以将const char* 转为string
forward_list<string> words(article.begin(),article.end());
当一个容器初始化为另外一个容器的拷贝时,两个容器的容器类型和元素类型都必须相同。
列表初始化
list<string> authors = {"Millon","Shakespeare","au"};
与顺序容器大小相关的构造函数
vector<int> ivec(10,-1);
list<string> svec(10,"hi");
只有顺序容器的构造函数才接受大小参数,关联容器并不支持
标准库array具有固定大小
array的大小是类型的一部分。还要指定array大小。
array<int,10> ia2 = {0,1,2,3};
对array进行列表初始化,初始值的数目必须等于或小于array的大小。
虽然不能对数组进行拷贝和对象赋值,但array并无此限制。
array<int,10> digits = {9,8,7,6};
array<int,10> copy = digits ;//正确

9.2.5 赋值和swap

赋值左右两边运算对象必须具有相同的类型
array<int,10> a2 = {0};//正确
a2 = {0};//错误,不能讲一个花括号列表赋值
array类型不支持assign和不允许用花括号包围的列表赋值。
使用assign
assign允许从一个不同但相容的类型赋值。
list<string> names;
vector<const char*> oldstyle;
names = oldstyle;//错误,类型不匹配
name.assign(oldstyle.cbegin(),oldstyle.cend());//正确
assign的第二个版本,接受一个整型值和一个元素值。
list<string> slist1(1)
slist1.assign(10,"hiya");//10个元素,都是"hiya"
使用swap
swap只是交换两个容器的内部结构,元素本身未交换。
意味着除string外,指向容器的迭代器、引用和指针在swap之后都不会失效。
对string调用swap会导致迭代器、引用和指针失效。

9.3顺序容器操作

名称
push_back
emplace_back
push_front
emplace_front
insert
front
emplace
back
at和下标操作
pop_back
pop_front
erase
clear
resize
vector
支持
支持
不支持
不支持
支持
支持
支持
支持
不支持
支持
支持
支持
deque
支持
支持
支持
支持
支持
支持
支持
支持
支持
支持
支持
支持
list
支持
支持
支持
支持
支持
支持
不支持
支持
支持
支持
支持
支持
forward_list
不支持
不支持
支持
支持
特殊版本
特殊版本
不支持
不支持
支持
特殊版本
支持
支持
array
不支持
不支持
不支持
不支持
不支持
不支持
支持
不支持
不支持
不支持
不支持
不支持
string
支持
支持
不支持
不支持
支持
支持
支持
支持
不支持
支持
支持
支持
向vector、string或deque插入元素会导致指向容器的迭代器、引用和指针失效。
insert返回的迭代器正好指向这个新插入的元素
调用emplace成员函数时候,将参数传递给元素类型的构造函数。
at成员函数,如果越界会返回一个out_of_range的异常
erase可以删除一个迭代器指定元素,也可以删除一对迭代器指定范围的所有元素。
forward_list未定义insert、emplace和erase,定义了insert_after、emplace_after和erase_after
容器操作可能让得迭代器失效
向容器添加元素
vector和string存储空间被重新分配,则指向容器的迭代器、指针和引用失效。未重新分配,则插入位置之前的迭代器、指针和引用有效,之后的失效。
deque,插入到首尾位置之外的任何位置都会导致失效。如果在首尾添加元素,迭代器失效,指针和引用不失效。
list和forwardlist,指向迭代器、引用和指针都有效。
删除元素
list和forward_list,指向其他位置的迭代器、指针和引用有效。
deque,首尾之外的任何位置删除元素,迭代器、指针和引用失效,如果删除尾元素,尾后迭代器失效,其他不受影响,删除首元素,都不受影响。
vector和string,被删位置之前的都有效。

9.4vector对象是如何增长

shrink_to_fit 只适用于vector、string和deque
capacity和reserve只适用于vector和string

9.5额外的string操作

string s(s2,pos2) ;//从s2的pos2开始的所有字符
stirng s(s2,pos2,len2) ;//从s2pos2开始len2长度字符
s.substr(pos,n);从pos开始,n个字符拷贝。
s.append(args)  ;对s进行追加
s.replace(range,args); 删除range范围内的字符,替换为args
s.find(args) 返回args第一次出现位置
s.rfind(args) 返回最后一次出现位置
s.find_first_of(args) args中的任何一个字符第一次出现位置
s.find_last_of(args) args中任何一个字符最后一次出现的位置
s.find_first_not_of(args) s中第一个不在args的字符
s.find_last_not_of(args) s中最后一个不在args的字符

9.6容器适配器

适配器让一种事物看起来像另外一种事物
stack、queue和priority_queue
每个适配器两个构造函数,一个创建空对象,一个接受容器的构造函数初始化适配器
stack<int> stk(deq);//deq是 dqueue<int>
stack和queue都是基于dqueue实现的。priority_queue是在vector上实现的
statck定义在stack头文件中,queue和priority_queue定义在queue中
  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值