4. 容器类型

4.1 通用操作

4.1.1 数学运算符

(1) +:用于拼接两个容器
(2) +=:用原容器与右侧容器拼接,并重新绑定变量
(3) *:重复生成容器元素
(4) *=:用原容器生成重复元素, 并重新绑定变量
(5) < <= > >= == !=:依次比较两个容器中元素,
一但不同则返回比较结果。
# 1. 拼接2个容器元素
name = "悟空"
name += "八戒"
print(name) # 悟空八戒
# 2. 容器元素重复
name = "唐僧"
name *= 2
print(name) # 唐僧唐僧
# 3. 比较运算:依次比较两个容器中元素,一但不同则返回比较结果。
print("悟空" > "唐僧")
练习:
在终端中获取一个整数,作为边长,打印矩形。
效果:
请输入整数:5
$$$$$
$   $
$   $
$   $
$$$$$
请输入整数:8
$$$$$$$$
$      $
$      $
$      $
$      $
$      $
$      $
$$$$$$$$

4.1.2 成员运算符

(1) 语法:
数据 in 序列
数据 not in 序列
(2) 作用:
如果在指定的序列中找到值,返回bool类型。
# 4. 成员运算
# True
print("悟空" in "我是齐天大圣孙悟空")
print("圣孙" in "我是齐天大圣孙悟空")
# False
print("齐圣" in "我是齐天大圣孙悟空")
print("圣大" in "我是齐天大圣孙悟空")

4.1.3 索引index

(1) 作用:定位单个容器元素。
(2) 语法:容器[整数]
(3) 说明:
	正向索引从0开始,第二个索引为1,最后一个
为len(s)-1。	
	反向索引从-1开始,-1代表最后一个,-2代表
倒数第二个,以此类推,第一个是-len(s)。
message = "我是花果山齐天大圣"
print(message[2]) # 花
print(message[-2]) # 大
print(len(message)) # 9
# 注意:索引不能越界IndexError
# print(message[99])
# print(message[-99])

4.1.4 切片slice

(1) 作用:
定位多个容器元素。
(2) 语法:
容器[开始索引:结束索引:步长]
(3) 说明:
结束索引不包含该位置元素
步长是切片每次获取完当前元素后移动的偏移量
开始、结束和步长都可以省略
message = "我是花果山齐天大圣"
print(message[2:5:1]) # 花果山
print(message[1: 5]) # 是花果山
print(message[2:-4]) # 花果山
print(message[:-4]) # 我是花果山
print(message[:]) # 我是花果山齐天大圣
print(message[-3:]) # 天大圣
print(message[:2]) # 我是
print(message[-2:]) # 大圣
print(message[-2: 3:-1]) # 大天齐山
print(message[1: 1]) # 空
print(message[2: 5:-1]) # 空
# 特殊:翻转
print(message[::-1]) # 圣大天齐山果花是我
练习:
字符串: content = "我是京师监狱狱长金海。"
打印第一个字符、打印最后一个字符、打印中间字符
打印字前三个符、打印后三个字符
命题:金海在字符串content中
命题:京师监狱不在字符串content中
通过切片打印“京师监狱狱长”
通过切片打印“长狱狱监师京”
通过切片打印“我师狱海”
倒序打印字符

4.1.5 内建函数

(1) len(x) 返回序列的长度
(2) max(x) 返回序列的最大值元素
(3) min(x) 返回序列的最小值元素
(4) sum(x) 返回序列中所有元素的和(元素必须是数值类型)

4.2 字符串 str

4.2.1 定义

由一系列字符组成的不可变序列容器,存储的是字符的编码值。

4.2.2 编码

4.2.2.1基础知识
(1) 字节byte:计算机最小存储单位,等于8 位bit.
(2) 字符:单个的数字,文字与符号。
(3) 字符集(码表):存储字符与二进制序列的对应关系。
(4) 编码:将字符转换为对应的二进制序列的过程。
(5) 解码:将二进制序列转换为对应的字符的过程。
4.2.2.2 编码方式
(1) ASCII编码:包含英文、数字等字符,
    每个字符1个字节。
(2) GBK编码:兼容ASCII编码,包含21003个
    中文;英文1个字节,汉字2个字节。
(3) Unicode字符集:国际统一编码,旧字符集
    每个字符2字节,新字符集4字节。
(4) UTF-8编码:Unicode的存储与传输方式,
    英文1字节,中文3字节。
4.2.2.1 相关函数
(1) ord(字符串):返回该字符串的Unicode码。
(2) chr(整数):返回该整数对应的字符串。
# 文字 --> 数字
number = ord("我")
print(number) # 25105
# 数字 --> 文字
char = chr(25105)
print(char) # 我
练习1:
在终端中录入一个内容,循环打印每个文字的编码值。
效果:
请输入文字:zjy
113	
116
120

练习:
循环录入编码值打印文字,直到输入空字符串停止。
效果:
请输入数字:113
z
请输入数字:116
j
请输入数字:
Process finished with exit code 0

4.2.3 字面值

4.2.3.1 单引和双引号的区别
(1) 单引号内的双引号不算结束符
(2) 双引号内的单引号不算结束符
4.2.3.2 三引号作用
(1) 换行会自动转换为换行符\n
(2)三引号内可以包含单引号和双引号
(3) 作为文档字符串
4.2.3.3 转义字符
(1) 定义:改变字符的原始含义。
(2) 语法:\'  \"  \n  \\ 
(3) 原始字符串:取消转义。
	a = r"C:\newfile\test.py"
4.2.3.4 字符串格式化
(1) 定义:生成一定格式的字符串。
(2) 语法:字符串%(变量)
	"我的名字是%s,年龄是%s" % (name)
(3) 类型码:%s字符串  %d整数  %f浮点数
print("%.2d:%.2d"%(2,3)) # 02:03
print("治愈比例为%d%%" % 5) # 治愈比例为5%
print("价格%.2f元" % (5 / 3)) # 价格1.67元
练习:
根据下列文字,提取变量,使用字符串格式化打印信息
湖北确诊67802人,治愈63326人,治愈率0.99
70秒是01分零10秒

4.3 列表 list

4.3.1 定义

由一系列变量组成的可变序列容器。

4.3.2 基础操作

(1) 创建列表:
列表名 = [] 
列表名 = list(可迭代对象)

(2) 添加元素:
列表名.append(元素)
列表.insert(索引,元素)

(3) 定位元素:
列表名[索引] = 元素
变量 = 列表名[索引]
变量 = 列表名[切片] # 赋值给变量的是切片所创建的新列表
列表名[切片] = 容器 # 右侧必须是可迭代对象,左侧切片没有创建新列表。

(4) 遍历:
正向:
 for 变量名 in 列表名:
变量名就是元素

反向:
for 索引名 in range(len(列表名)-1,-1,-1):
列表名[索引名]就是元素

(5) 删除元素:
列表名.remove(元素)
del 列表名[索引或切片]
# 1. 创建
# 写法1:列表名 = [数据1,数据2]
# 姓名列表
list_names = ["悟空", "唐三藏", "八戒", "沙僧"]
# 年龄列表
list_ages = [26, 23, 25, 16]
# 写法2:列表名 = list(可迭代对象)
list_name = list("孙悟空")
print(list_name) # ['孙', '悟', '空']
# 2. 添加
# -- 追加:列表名.append(数据)
list_names.append("小白龙")
# -- 插入: 列表名.insert(索引,数据)
list_names.insert(2, "哪吒")
print(list_names) # ['悟空', '唐三藏', '哪吒', '八戒', '沙僧', '小白龙']
# 3. 定位
# -- 索引:容器名[整数]
# -- 读取
element = list_names[-1]
print(element) # 小白龙
# -- 修改
list_names[-1] = "二郎神"
print(list_names) # ['悟空', '唐三藏', '哪吒', '八戒', '沙僧', '二郎神']
# -- 切片:容器名[整数:整数:整数]
# -- 通过切片读取,创建新列表(拷贝)
names = list_names[:3]
print(names) # ['悟空', '唐三藏', '哪吒']
# -- 通过切片修改,遍历右侧数据,依次存入左侧.
list_names[:3] = ["空空", "唐唐", "猪猪"]
# list_names[:3] = 100 # 因为100不能被for
list_names[:3] = "孙悟空"
print(list_names) # ['孙', '悟', '空', '八戒', '沙僧', '二郎神']
# 4. 遍历:操作容器每个元素
# -- 方式1: for 元素 in 容器
# 适用性:从头到尾依次读取
for name in list_names:
print(name)
# -- 方式2:for 索引 in range(开始,结束,间隔):
# 适用性:非从头到尾依次读取
# len(list_names) - 1 是 最大索引(总数-1)
# -1 索引可以去到0
# -1 倒序
# 功能:倒序
for i in range(len(list_names) - 1, -1, -1):
print(list_names[i])
# 功能:修改
for i in range(len(list_names)):
# 文字长度是3的修改为None
if len(list_names[i]) == 3:
list_names[i] = None
print(list_names) # ['孙', '悟', '空', '八戒', '沙僧', None]
# 5. 删除
# -- 方式1:根据元素删除 列表名.remove(元素)
list_names.remove("八戒")
# -- 方式2:根据定位删除 del 容器名[索引或者切片]
del list_names[0]
del list_names[-2:]
print(list_names) # ['悟', '空']
练习1:
八大行星:"水星" "金星" "地球" "火星" "木星" "土星" "天王星" "海王星"
-- 创建列表存储4个行星:“水星” "金星" "火星" "木星"
-- 插入"地球"、追加"土星" "天王星" "海王星"
-- 打印距离太阳最近、最远的行星(第一个和最后一个元素)
-- 打印太阳到地球之间的行星(前两个行星)
-- 删除"海王星",删除第四个行星
-- 倒序打印所有行星(一行一个)

4.3.3 深拷贝和浅拷贝

浅拷贝:复制过程中,只复制一层变量,不会复制深层变量绑定的对象的复制过程。
深拷贝:复制整个依懒的变量。

练习1:画出下列代码内存图
list01 = ["北京", "上海"]
list02 = list01
list01[0] = "广东"
list03 = list01[:]
list03[-1] = "深圳"
print(list01)#?
练习2:画出下列内存图
list01 = ["北京", "上海", "深圳"]
list02 = list01
list01.insert(0,"天津")
del list01[1]
print(list02)# ?
练习3:画出下列内存图
import copy
list01 = ["北京",["上海","深圳"]]
list02 = list01
list03 = list01[:]
list04 = copy.deepcopy(list01)
list04[0] = "北京04"
list04[1][1] = "深圳04"
print(list01) # ?
list03[0] = "北京03"
list03[1][1] = "深圳03"
print(list01) # ?
list02[0] = "北京02"
list02[1][1] = "深圳02"
print(list01) # ?

4.3.4 列表与字符串转换

(1) 列表转换为字符串:
    result = "连接符".join(列表)
list01 = ["a", "b", "c"]
result = "-".join(list01)
print(result)
练习:
在终端中,循环录入字符串,如果录入空则停止.	
停止录入后打印所有内容(一个字符串)
效果:
请输入内容:香港
请输入内容:上海
请输入内容:新疆
请输入内容:
香港_上海_新疆

(2) 字符串转换为列表:
列表 = “a-b-c-d”.split(“分隔符”)
# 使用一个字符串存储多个信息
list_result = "唐僧,孙悟空,八戒".split(",")
print(list_result)
练习:将下列英文语句按照单词进行翻转.
转换前:To have a government that is of people by people for people
转换后:people for people by people of is that government a have To

4.3.5 列表推导式

(1) 定义:
使用简易方法,将可迭代对象转换为列表。
(2) 语法:
变量 = [表达式 for 变量 in 可迭代对象]
变量 = [表达式 for 变量 in 可迭代对象 if 条件]
(3) 说明:
如果if真值表达式的布尔值为False,则可迭代对象生成的数据将被丢弃。
list01 = [9, 15, 65, 6, 78, 89]
# 需求:在list01中挑出能被3整除的数字存入list02
# list02 = []
# for item in list01:
# if item % 3 == 0:
# list02.append(item)
list02 = [item for item in list01 if item % 3 == 0]
print(list02)
# 需求:在list01中所有数字的个位存储list03
# list03 = []
# for item in list01:
# list03.append(item % 10)
list03 = [item % 10 for item in list01]
print(list03)
练习:
生成10--30之间能被3或者5整除的数字
[10, 12, 15, 18, 20, 21, 24, 25, 27]
生成5 -- 20之间的数字平方
[25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361]

(4) 列表推导式嵌套
变量 = [表达式 for 变量1 in 可迭代对象1 for 变量2 in可迭代对象2]
#result = []
#for r in ["a", "b", "c"]:
# for c in ["A", "B", "C"]:
# result.append(r + c)
result = [r + c for r in list01 for c in list02]

4.4 元组 tuple

4.4.1 定义

(1) 由一系列变量组成的不可变序列容器。
(2) 不可变是指一但创建,不可以再添加/删除/修改元素。 

4.4.2 基础操作

(1) 创建空元组:
元组名 = ()
元组名 = tuple()

(2) 创建非空元组:
元组名 = (20,)
元组名 = (1, 2, 3)
元组名 = 100,200,300
元组名 = tuple(可迭代对象)

(3) 获取元素:
变量 = 元组名[索引]
变量 = 元组名[切片] # 赋值给变量的是切片所创建的新列表

(4) 遍历元组:
正向:
    for 变量名 in 列表名:
   变量名就是元素
反向:
    for 索引名 in range(len(列表名)-1,-1,-1):
   元组名[索引名]就是元素
# 1. 创建
# -- 元组名 = (元素1, 元素2, 元素3)
tuple01 = (10, 20, 30)
# -- 元组名 = tuple( 可迭代对象 )
list01 = ["a", "b", "c"]
tuple02 = tuple(list01)
# 2. 定位
# -- 读取(索引/切片)
print(tuple01[0]) # 10
print(tuple01[:2]) # (10, 20)
# 3. 遍历
for item in tuple01:
print(item)
for i in range(len(tuple01) - 1, -1, -1):
print(tuple01[i])
# 4. 特殊
# 注意1:小括号可以省略
tuple03 = 10, 20, 30
# 注意2:如果元组中只有一个元素,必须有逗号
tuple04 = (10,)
# 拆包: 多个变量 = 容器
# a,b,c = tuple03
# a,b,c = ["A","B","C"]
a,b,c = "孙悟空"
*a,b = "孙悟空"
print(a) # ['孙', '悟']
print(b) # 空
练习2:
根据月日,计算是这一年的第几天.
公式:前几个月总天数 + 当月天数
例如:5月10日
计算:31 29 31 30 + 10

4.4.3 作用

(1) 元组与列表都可以存储一系列变量,由于列表会预留内存空间,所以可以增加元素。

(2) 元组会按需分配内存,所以如果变量数量固定,建议使用元组,因为占用空间更小。

(3) 应用:变量交换的本质就是创建元组:x, y = (y, x )
格式化字符串的本质就是创建元祖:"姓名:%s, 年龄:%d" % ("tarena", 15)

4.5 字典 dict

4.5.1 定义

(1) 由一系列键值对组成的可变散列容器。
 (2) 散列:对键进行哈希运算,确定在内存中的存储位置,每条数据存储无先后顺序。
(3) 键必须惟一且不可变(字符串/数字/元组),值没有限制。

4.5.2 基础操作

(1) 创建字典:
字典名 = {键1:值1,键2:值2}
字典名 = dict (可迭代对象)

(2) 添加/修改元素:
语法:
字典名[键] = 数据
说明:
键不存在,创建记录。
键存在,修改值。

(3) 获取元素:
变量 = 字典名[键] # 没有键则错误

(4) 遍历字典:
for 键名 in 字典名:
字典名[键名]
for 键名,值名 in 字典名.items():
语句

(5) 删除元素:
del 字典名[键]
# 1. 创建
# -- { 键1:值1, 键2:值2 }
dict_wk = {"name": "悟空", "age": 25, "sex": "女"}
dict_bj = {"name": "八戒", "age": 26, "sex": "男"}
dict_xbl = {"name": "小白龙", "age": 23, "sex": "女"}
# -- dict( [( , ),( , )] )
# 列表转换为字典的格式要求:列表元素必须能够"一分为二"
list01 = ["八戒", ("ts", "唐僧"), [1001, "齐天大圣"]]
dict01 = dict(list01)
# 2. 添加 字典名[键] = 值
dict_wk["money"] = 100000
print(dict_wk) # {'name': '悟空', 'age': 25, 'sex': '女', 'money': 100000}
# 字典不能使用 索引 切片
# 3. 定位:字典名[键]
# -- 读取
print(dict_wk["name"])
# 注意:如果没有键则报错
# 解决:读取数据前,通过in判断.
if "money" in dict_wk:
print(dict_wk["money"])
# -- 修改(与添加数据语法相同)
# 具有key为修改,没有key为添加
dict_wk["name"] = "空空"
print(dict_wk) # {'name': '空空', 'age': 25, 'sex': '女', 'money': 100000}
# 4. 删除 del 字典名[键]
del dict_wk["sex"]
print(dict_wk) # {'name': '空空', 'age': 25, 'money': 100000}
# 5. 遍历
# 方式1:for 键 in 字典名称
for key in dict_wk:
print(key)
# 方式2:for 值 in 字典名称.values()
for value in dict_wk.values():
print(value)
# 方式3:for 键,值 in 字典名称.items()
for key,value in dict_wk.items():
print(key)
print(value)
# 数据类型名称( ... )
# [('name', '李佳豪'), ('age', 25), ('sex', '女')]
print(list(dict_wk.items())) # [('name', '空空'), ('age', 25), ('money',
100000)]

4.5.3 字典推导式

(1) 定义:
使用简易方法,将可迭代对象转换为字典。
(2) 语法:
{键:值 for 变量 in 可迭代对象}
{键:值 for 变量 in 可迭代对象 if 条件}

练习1:
将两个列表,合并为一个字典
姓名列表["张无忌","赵敏","周芷若"]
房间列表[101,102,103]
{101: '张无忌', 102: '赵敏', 103: '周芷若'}

练习2:
颠倒练习1字典键值
{'张无忌': 101, '赵敏': 102, '周芷若': 103}

4.6 集合 set

4.6.1 定义

(1) 由一系列不重复的不可变类型变量(元组/数/字符串)组成的可变散列容器。
(2) 相当于只有键没有值的字典(键则是集合的数据)。

4.6.2 基础操作

(1) 创建空集合:
集合名 = set()
集合名 = set(可迭代对象)

(2) 创建具有默认值集合:
集合名 = {1, 2, 3}
集合名 = set(可迭代对象)

(3) 添加元素:
集合名.add(元素)

(4) 删除元素:
集合名.discard(元素)
# 1. 创建
# -- 集合名 = {元素1,元素2,元素3}
set01 = {"悟空", "唐僧", "八戒"}
list01 = ["唐僧", "悟空", "唐僧", "八戒", "唐僧"]
# -- 集合名 = set(可迭代对象)
set02 = set(list01)
print(set02) # {'八戒', '悟空', '唐僧'}
# 2. 添加:集合名.add(元素)
set02.add("小白龙")
print(set02) # {'悟空', '八戒', '小白龙', '唐僧'}
# 定位
#(因为无序不能使用索引切片)
#(因为不是键值对不能使用键查找键)
# 3. 遍历
for item in set01:
print(item)
# 4. 删除
if "悟空1" in set01:
set01.remove("悟空1")

4.6.3 运算

(1) 交集&:返回共同元素.
s1 = {1, 2, 3}
s2 = {2, 3, 4}
s3 = s1 & s2 # {2, 3}
(2) 并集:返回不重复元素
s1 = {1, 2, 3}
s2 = {2, 3, 4}
s3 = s1 | s2 # {1, 2, 3, 4}
(3) 补集-:返回只属于其中之一的元素
s1 = {1, 2, 3}
s2 = {2, 3, 4}
s1 - s2 # {1} 属于s1但不属于s2
(4) 补集^:返回不同的的元素
s1 = {1, 2, 3}
s2 = {2, 3, 4}
s3 = s1 ^ s2 # {1, 4} 等同于(s1-s2 | s2-s1)
(5) 子集<:判断一个集合的所有元素是否完全在另一个集合中

(6) 超集>:判断一个集合是否具有另一个集合的所有元素
s1 = {1, 2, 3}
s2 = {2, 3}
s2 < s1 # True
s1 > s2 # True
(7) 相同或不同== !=:判断集合中的所有元素是否和另一个集合相同。
s1 = {1, 2, 3}
s2 = {3, 2, 1}
s1 == s2 # True
s1 != s2 # False
子集或相同,超集或相同 <= >=

练习:一家公司有如下岗位:
 "经理":"曹操","刘备","孙权"
 "技术" :"曹操","刘备","张飞","关羽"
	1. 定义数据结构,存储以上信息.
	2. 是经理也是技术的都有谁?
	3. 是经理不是技术的都有谁?
	4. 不是经理是技术的都有谁?
	5. 身兼一职的都有谁?
	6. 公司总共有多少人数?

4.6.4 集合推导式

(1) 定义:
使用简易方法,将可迭代对象转换为集合。
(2) 语法:
{表达式 for 变量 in 可迭代对象}
{表达式 for 变量 in 可迭代对象 if 条件}

4.7 容器综合训练

练习1:在终端中打印如下图形
$
$$
$$$
$$$$

练习2:二维列表
list01 = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
]
1. 将第一行从左到右逐行打印
效果:
1
2	
3
4
5

2. 将第二行从右到左逐行打印
效果:
10
9
8
7
6

3. 将第三列行从上到下逐个打印
效果:
3
8
13

4. 将第四列行从下到上逐个打印
效果:
14
9
4

5. 将二维列表以表格状打印
效果:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

练习3:多个人的多个爱好
dict_hobbies = {
"于谦": ["抽烟", "喝酒", "烫头"],
"郭德纲": ["说", "学", "逗", "唱"],
}
1. 打印于谦的所有爱好(一行一个)
效果:
抽烟
喝酒
烫头

2. 计算郭德纲所有爱好数量
效果:4

3. 打印所有人(一行一个)
效果:
于谦
郭德纲

4. 打印所有爱好(一行一个)
抽烟
喝酒
烫头
说
学
逗
唱

练习4:
dict_travel_info = {
"北京": {
"景区": ["长城", "故宫"],
"美食": ["烤鸭", "豆汁焦圈", "炸酱面"]
},
"四川": {
"景区": ["九寨沟", "峨眉山"],
"美食": ["火锅", "兔头"]
}
}
1. 打印北京的第一个景区
效果:
长城

2. 打印四川的第二个美食
效果:
兔头

3. 所有城市 (一行一个)
效果:
北京
四川

4. 北京所有美食(一行一个)
效果:
烤鸭
豆汁焦圈
炸酱面

5. 打印所有城市的所有美食(一行一个)
效果:
烤鸭
豆汁焦圈
炸酱面
火锅

练习5:
对数字列表进行升序排列(小 --> 大)

练习6:
# 商品字典
dict_commodity_infos = {
1001: {"name": "屠龙刀", "price": 10000},
1002: {"name": "倚天剑", "price": 10000},
1003: {"name": "金箍棒", "price": 52100},
1004: {"name": "口罩", "price": 20},
1005: {"name": "酒精", "price": 30},
}
# 订单列表
list_orders = [
{"cid": 1001, "count": 1},
{"cid": 1002, "count": 3},
{"cid": 1005, "count": 2},
]
1. 打印所有商品信息,
 格式:商品编号xx,商品名称xx,商品单价xx.

2. 打印所有订单中的信息,
格式:商品编号xx,购买数量xx.

3. 打印所有订单中的商品信息,
格式:商品名称xx,商品单价:xx,数量xx.

4. 查找数量最多的订单(使用自定义算法,不使用内置函数)

5. 根据购买数量对订单列表降序(大->小)排列
好的,让我来一一回答你的问题。 1. 顺序容器包括 vector、deque 和 list 三种。它们的基础数据结构分别是动态数组、双端队列和双向链表。其中,vector 在尾部插入和删除元素的时间复杂度为 O(1),在其他位置插入和删除的时间复杂度为 O(N);deque 在两端插入和删除元素的时间复杂度均为 O(1);list 在任意位置插入和删除元素的时间复杂度均为 O(1)。另外,vector 和 deque 支持随机访问,而 list 不支持。 2. 容器的共性包括:存储数据、提供访问数据的接口、实现数据的插入和删除、管理数据的内存分配和释放。 3. 容器适配器与标准容器之间的关系是,容器适配器是在标准容器的基础上提供了一些额外的功能,如 stack 和 queue 分别基于 deque 和 list 实现,提供了后进先出和先进先出的操作。 4. 关联容器包括 set、multiset、map 和 multimap 四种。其中,set 和 multiset 存储的是有序不重复的元素,map 和 multimap 存储的是有序键值对,键是唯一的。set 和 map 的底层实现是红黑树,multiset 和 multimap 的底层实现也是红黑树,但允许有重复的元素或键。 5. 表5.6对本章所介绍的容器进行了比较,包括底层数据结构、主要成员函数、是否支持[]与at()、数据插入方法、数据删除方法、成员是否有序、迭代器类型等方面。 6. 在运行效率方面,vector 的 erase 操作的时间复杂度为 O(N),因为要将后面的元素向前移动,而 list 的 erase 操作的时间复杂度为 O(1),因为只需要修改指针。在返回值方面,vector 的 erase 函数返回的是指向删除元素后一个元素的迭代器,而 list 的 erase 函数返回的是指向下一个元素的迭代器。下面是一个简单的程序,展示了 vector 和 list 的 erase 函数的差异: ```c++ #include <iostream> #include <vector> #include <list> int main() { std::vector<int> vec{1, 2, 3, 4, 5}; auto itv = vec.erase(vec.begin() + 2); // 删除元素3 for (auto i : vec) std::cout << i << " "; // 输出:1 2 4 5 std::cout << "\n"; std::cout << *itv << "\n"; // 输出:4 std::list<int> lst{1, 2, 3, 4, 5}; auto itl = lst.erase(++lst.begin()); // 删除元素2 for (auto i : lst) std::cout << i << " "; // 输出:1 3 4 5 std::cout << "\n"; std::cout << *itl << "\n"; // 输出:3 return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值