多一些Aha Time,发现技术的美妙🍺|

啊原来是这样呀

园龄:8年3个月粉丝:3关注:9

【C++】12.序列与关联容器[深蓝学院C++第10章]

前言

 

一.容器概述

一种特殊的类型,其对象可以放置其他类型的对象(元素)

需要支持的操作:通常包括添加、删除、索引、遍历

有多种算法可以实现容器,每种方法各有利弊

1.1 分类

序列容器:其中的对象有序排列,一般使用下标进行索引

关联容器:其中的对象顺序并不重要,使用键进行索引

适配器:调整原有容器的行为,使其对外展现出新的类型、接口或返回新的元素

生成器:构造元素序列

1.2 迭代器

用于指定容器中的一段区间,以执行遍历、删除等操作

获取迭代器:(c)begin/(c)end,带c的是const。rbegin和rend,逆向遍历

 

 分为5类、5种categary,不同的类别支持的操作集合不同

(1)input iterator

(2)output interator

(3)forward interator:兼具input和output

(4)bidirectional iterator,双向

(5)random access iterator,可以++、--

二.序列容器

2.1 标准库提供的序列容器

(1)array,元素固定的序列容器

(2)vector,元素连续存储的序列容器

(3)forward_list/list,基于链表、双向链表的容器

(4)deque,vector和list的这种,双向队列

(5)basic_string,提供了对字符串专门的支持

需要指定元素类型来实例化

不同的容器所提供的接口大致相同,容器不同其内部复杂度不同

对于复杂度过高的操作,提供相对较难使用的接口或者不提供相应的接口

2.2 array

具有固定长度的容器,其内部维护了一个内建数组,与内建数组相比提供了复制

接口:

(1)构造,std::array<int,用户指定size> a = {集合初始化};

(2)读取成员类型:value_type等

(3)元素访问,[]、at、front、back、data(传入数组指针)

(4)容器相关:empty、size、max_size

(5)填充和交换:fill、swap

(6)比较操作:<=> spaceship operator,用来返回比较结果的枚举值,按照字典序来比较

(7)迭代器,begin、end

2.3 vector

元素可变

接口:

(1)与array相似

(2)容量相关的:capacity容量、reserve翻转、shrink_to_fit削减多余的空间

(3)附加元素接口:push_back、emplace_back

(4)元素插入接口:insert、emplace

(5)元素删除接口:pop_back、erase、clear

注意:

(1)vector不提供push_front、pop_front,可以使用insert(造成后挪)、erase(造成前挪)模拟但比较慢

(2)swap效率较高

(3)写操作可能导致迭代器失效

2.4 list

双向链表

与vector相比,list:

(1)插入、删除成本较低,但随机访问成本较高

(2)提供了pop_front、splice等接口,splice可以把某list一次性挪入另外一个list

(3)写操作通常不会改变迭代器的有效性

forward_list的特性:

(1)单向链表,一个成本比较低的线性表实现

(2)其迭代器只支持递增操作,无rbegin和rend

(3)不支持size

(4)不支持pop_back和push_back

(5)xxx_after操作,只能在某个元素后面作一系列操作

2.5 deque

双向队列/双端队列,是vector和list的折中

特性:

(1)push_back/push_front速度较快

(2)在序列中间插入、删除较慢

2.6 basic_string

实现了字符串相关的接口

特性:

(1)使用char实例化出std::string

(2)提供了如find、substr等字符串特有的接口

(3)提供了数值与字符串转换的接口,to_string,stoi\stol等

(4)针对短字符串的优化,略

 

三.关联容器

关联容器,存在某种映射

3.1 索引

使用键进行索引

set/map/multiset/multimap

unordered_set / unordered_map / unordered_multiset / unordered_multimap

3.2 底层实现

set/map/multiset/multimap底层使用红黑树实现,有序方便搜索

unordered_xxx底层使用hash表实现,以便快速地查询是否元素已存在

3.3 set

底层用红黑树来实现,是一个二叉平衡搜索树

 

特性:

(1)从映射角度来理解,set中有某个元素时value为true、没有某个元素时value为false

(2)从有序角度来理解,set中的顺序是不重要的,但实际在存储时是有序的

功能:

(1)通常元素需要支持使用<比较大小,以便排序

(2)可以指定less或greater,或引入自定义的比较函数来比较大小关系

(3)插入元素,insert、emplace、emplace_hint(给出提示,提高插入速度)

(4)删除元素,erase

(5)访问元素,find、contains

(6)修改元素,extract返回节点对象,可以设置它的.value()

注意:set迭代器所指向的对象是const的,不能通过其修改元素

3.4 map

 

 特性:

(1)树中每个节点是一个std::pair,->first为键,->second为value

(2)键需要支持使用<比较大小

(3)或者采用自定义的比较函数来引入大小关系

(4)访问元素:find、contains、[]、at,[]访问时如果没有key会自动创建

(5)删除元素:erase(key)

注意:

(1)map迭代器所指向的对象是std::pair,其键是const

(2)[]操作不能用于常量对象

3.5 multiset和multimap

与set和map类似,但允许重复键

元素访问:

(1)find返回首个查找到的元素

(2)count返回元素个数

(3)lower_bound/upper_bound/equal_range返回查找到的区间,lower和upper是找到的上下界,equal是起止迭代器

3.6 unordered_set/unordered_map/unordered_multiset/unordered_multimap

 

 unordered,无序的

使用hash作键

特性:

(1)与set、map相比查找性能更好

(2)插入操作一些情况下会慢

(3)键需要支持两个操作,1是转换为hash值,2是判等

(4)除==和!=外,不支持容器级的关系运算,==和!=的运算较慢

(5)自定义hash与判等函数

 

四.适配器与生成器

4.1 类型适配器

basic_string_view

basic_string_view中的basic_string是一个字符容器,用于解决char*和string转换时的开销,统一起来方便使用

void fun(std::string_view str){

  if(str.empty()) xxx;

}

可以直接传入char*或string

特性:

(1)可以基于std::string,C字符串,迭代器这三者进行构造

(2)构造成本很低,提供成本较低的操作接口

(3)只提供读,不可进行写操作

span

void fun(std::span<int> input){

  input可以用for-range进行访问

}

int a[3]={1,2,3};

fun(a);

span是C++20引入的,提供对连续对象的封装

(1)可基于C数组、array等构造

(2)可读写

4.2 接口适配器

stack/queue/priority_queue

对底层序列容器进行封装,对外展现栈、队列与优先队列的接口

priority_queue在使用时其内部包含的元素需要支持比较操作

4.3 数值适配器

c++20引入,暂略

4.4 生成器

c++20引入,暂略

 

本文作者:OhOfCourse

本文链接:https://www.cnblogs.com/OhOfCourse/p/17173290.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   啊原来是这样呀  阅读(21)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起