您的位置:首页 > 编程语言 > C语言/C++

C++primer 第九章笔记 初稿

2017-02-08 19:19 148 查看

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_referenceconst左值
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)。

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

迭代器有公共的接口,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:新加入的元素排在优先级比其低的元素之前。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: