首页 > 编程 > C++ > 正文

C++primer 第九章笔记 初稿

2019-11-10 17:29:56
字体:
来源:转载
供稿:网友

9.1 顺序容器

性质:容器中元素的顺序与加入的位置相对应,为使用者提供了控制元素存储和访问顺序的能力。

六大顺序容器

名称 功能 特点>
vector 可变大小数组 支持快速随机访问,除尾部外插入、删除较慢
deque 双端队列 支持快速随机访问,头尾外插入删除较慢
list 双向列表 支持双向顺序访问,任何位置插入删除很快
forward_list 单项列表 支持正向顺序访问,任何位置插入删除很快
array 固定大小数组 支持快速随机访问,不能添加删除
string 字符串 支持快速随机访问,除尾部外插入、删除较慢
list与forward_list相较有更大的额外内存消耗。 array相比内置数组更为安全。 标准库运行效率较高,应当优先选择标准库而不是原式数据结构。 如果程序只要在读取时才会向容器中间插入数据,可以设定一个list缓冲。

9.2顺序容器概览(一般操作)

类型与函数 描述
iterator 迭代器
const_iterator 只读迭代器
size_type 无符号整型,描述容器大小或迭代器位置差
difference_type 带符号整型
value_type 元素类型
reference 元素左值类型,与value_type&相似
const_reference const左值
C c, C c(c2), C c(b,e) 构造函数
C c{a,b,c,d…} 构造函数
C c(n), C c(n,t) 构造函数,n为个数,t为初始值
c1=c2, c1={a,b,c,d,…} 赋值
a.swap(b), swap(a,b) 交换
c.size() 元素个数(不支持forward_list
c.max_size() 容器可保存最多元素个数
c.empty() 确认容器是否为空
c.insert(args) 插入元素
c.emplace(inits) 构造一个元素
c.erase(args) 删除元素
c.clear() 清空容器
reverse_iterator 逆寻址迭代器
const_reverse_iterator 只读逆寻址迭代器
c.rbegin(), c.rend(), c.crbegin(), c.crend 返回逆寻址迭代器

对于C c(b,e)的构造方法,C所声明的容器元素类型,必须与b e的类型相容(不一定一样,除array)。

比较运算符必须要求容器中的元素允许元素运算。

迭代器有公共的接口,forward_list不支持自减操作。

对反向迭代器使用自增,等价于正向迭代器递减。

迭代器初始化与拷贝初始化区别

list<string> ls;vector<const char*> vcc;list<string> ls2(ls);//正确无疑deque<string>ds(ls);//错误,容器种类不同 vector<string>vs(vcc)//错误,容器元素类型不同forward_list<string>fs(vcc.begin(),vcc.end());//正确 array支持容器直接拷贝(内置数组当然不行),但是类型和长度必须都一致。不支持assign与列表赋值。

9.3 顺序容器操作

赋值与交换

交换两个容器的元素通常比拷贝元素快,除array不涉及任何元素拷贝、删除、插入,故在常数时间完成。

赋值会导致左值容器的迭代器、引用、指针失效,而交换会导致所有迭代器、引用、指针失效(array,string除外)。

assign

assign(b,e):b和e不能是调用容器的迭代器。assign(n,t):全部替换,没有部分替换的方法。

交换两个array用线性时间,但是元素值改变的同时迭代器所表示的位置不变。

添加元素

push_back()

不支持forward_list。本质是添加拷贝。返回void。

push_front

支持list,forward_list,deque。在最开头插入元素,返回void。

insert

对push_front不支持不代表对insert插入开头不支持。

在迭代器指向元素之前插入,且返回第一个插入元素的迭代器。

通过将返回值赋值给原迭代器,可实现在同一位置反复插入元素。

也有返回void版本的insert方法。

emplace :直接进行初始化

访问元素

front:返回首元素的引用,通过*(c.begin())也可得到。

back:返回尾元素的引用,forward_list无,通过*(c.end()-1)也可得到。

at(n):返回下标为n的元素的引用。

删除元素

pop_front, pop_back

pop_back不支持forward_list,pop_front不支持vector、string。

分别删除首元素与尾元素,容器不可为空,返回void。

erase:

删除单个或范围元素,返回被删除的最后一个元素之后的迭代器。

删除单个尾后迭代器是未定义的,范围包含尾后迭代器是可以的。

forward_list

特殊原因:作为单向链表,无法通过简答方法获得元素的前驱,故通过改变给定元素之后的元素来实现。

insert_after:返回指向最后一个插入元素的迭代器。

emplace_after(p,args):插入元素args,返回指向插入元素的迭代器。

erase_after(p):删除p指向位置之后的元素,返回指向被删除元素之后的迭代器。

erase_after(b,e):删除[b,e)之间的元素,且返回指向被删除元素之后的迭代器。

在forward_list中,通常会有两个变量,一个记录当前迭代器,一个记录前驱迭代器。

forward_list<int> fl = {0,1,2,3,4,5,6,7,8,9};auto PRev=fl.before_begin();auto curr=fl.begin();while(curr!=fl.end()){ if (*curr % 2) curr = fl.erase_after(prev); else prev = curr++;}

注意点:一旦涉及到容器的插入删除,不要缓存迭代器(end()),应当每次使用都调用一次。

9.4 vector对象的增长方式

capacity:当前容器上限元素个数reserve:给容器分配更大的空间(小于等于当前空间不会报错,但是什么也不做)

shrink_to_fit:将上限减少到与size()相匹配的大小。

vector重新分配内存时一般上限*2。

9.5 string的额外操作

构造方法

(cp,n) cp指向的数组中的,前n个元素的拷贝。如果不传递n,指针所指向的数组必须以 ‘/n’ 结尾!

(s2,pos2) 从string类对象s2的下标pos2开始的拷贝,pos2大于s2.size()为未定义的行为。

(s2,pos2,len2) 从string类对象s2的下标pos2开始len2个字符的拷贝,pos2大于s2.size()为未定义的行为,len2过长不影响正常运行。

s.substr(pos,n) 返回字符串s从pos到pos+n-1的子串的拷贝。

其他操作

存在基于下标运算的insert、erase、assign方法。

append(args):类似于”+”。

replace(range,args):range为pos开始len长个字符,或者是一对迭代器。

搜索操作

返回值:string::size_type或string::npos。

find(args) 返回调用对象中第一个匹配s的位置的下标,不存在则返回npos。

rfind(args) 返回调用对象中最后一个匹配s的位置的下标,不存在则返回npos。find_first_of(args)、find_last_of(args) 返回第一次/最后一次args中任一字符出现的位置。find_first_not_of(args)、find_last_not_of(args) 返回第一次/最后一次不在args中出现的字符位置。样例:查找数字字符 #include <iostream>#include <cstring>using namespace std;int main(){ string s="ab2c3d7R4E6"; string sn="0123456789"; string::size_type pos=0; while((pos=s.find_first_of(sn,pos))!=string::npos){ cout<<s[pos]<<endl; pos++; } pos=0; while((pos=s.find_first_not_of(sn,pos))!=string::npos){ cout<<s[pos]<<endl; pos++; } return 0;}

compare方法:类似于strcmp。

数值转换:一般为sto + 类型首字母 + (s,p,b),p为第一个非数值字符的下标,b为基数默认10。 string s="a=1";int i=stoi(s.substr(s.find_first_of(0123456789)));

9.6 顺序容器适配器

定义:接受一种已有容器,并使其有接收适配器的操作。

定义适配器

与容器定义类似。

默认下,stack 和 queue 是基于deque实现的,而priority_queue是基于vector实现的。

通过创建适配器时将命名的顺序容器作为第二个参数,可以重载默认容器类型。

stack<string, vector<string>>str_stk(svec);

限制

适配器不能构造于array、forward_list之上。queue不能构造于vector之上,priority_queue不能构造于list之上。适配器不可以调用底层容器专有的方法。

特征

queue:先进先出,即进入队列的对象被放置到对尾。priority_queue:新加入的元素排在优先级比其低的元素之前。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选