c++ - set、map、multiset、multimap容器介绍和常用接口使用

news2024/11/15 21:30:39

文章目录

    • 前言
    • 一、set容器
    • 二、multiset
    • 三、map
    • 四、multimap


前言

1、set、map、 multiset、 multimap都是基于红黑树实现的容器。
2、set、multiset都使用头文件#include<set>,map、multimap都是使用头文件#include<map>

一、set容器

1、set容器的介绍

C++标准库中的set容器是一种关联容器,它存储的元素是唯一的,并且以特定的顺序排列。set容器基于红黑树实现,这意味着它可以提供对数时间复杂度的插入、删除和查找操作。

2、set容器的特性

(1)唯一性:set中的每个元素都必须是唯一的,因为set通过其值来标识元素,而不是通过位置或索引。
(2)自动排序:set中的元素会根据其值自动排序。默认情况下,使用元素类型的<运算符进行排序,但可以指定自定义的比较函数来改变排序规则。
(3)对数时间复杂度:插入、删除和查找操作的时间复杂度为O(log n),其中n是容器中元素的数量。
(4)不支持直接元素访问:与vector或deque等序列容器不同,set不支持通过位置直接访问元素。要访问元素,必须使用迭代器或通过其值来查找。
(5) 与map/multimap不同,map/multimap中存储的是真正的键值对<key, value>,set中只放
value,但在底层实际存放的是由<value, value>构成的键值对
(6) set中插入元素时,只需要插入value即可,不需要构造键值对。
(7)不支持修改元素:因为set的设计初衷是为了维护一个唯一且自动排序的元素集合。如果允许直接修改 元素的值,那么可能会破坏set的这两个核心特性:
唯一性:set中的每个元素都必须是唯一的。如果允许修改元素的值,那么可能会使得原本唯一的元素变得不唯一,比如将一个元素修改为set中已存在的另一个元素的值。
自动排序:set中的元素会根据其值自动排序。如果允许修改元素的值,那么可能会破坏原有的排序顺序,使得set无法再按照预期的顺序来遍历或查找元素。

3、set容器使用
(1)模板参数:
在这里插入图片描述

T: set中存放元素的类型,实际在底层存储<value, value>的键值对。
Compare:set中元素默认按照小于来比较。
Alloc:set中元素空间的管理方式,使用STL提供的空间配置器管理
注意:一般只传第一个参数,如果需要按照特定条件排序可以自定义一个比较仿函数作为第二个参数,第三个基本不用传。

(2)常用构造、赋值接口

函数声明功能
set (const Compare& comp = Compare(), const Allocator& = Allocator() );构造空的set
set (InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator() );用[first, last)区间中的元素构造set
set ( const set<Key,Compare,Allocator>& x);set的拷贝构造
set& operator= (const set& x);进行赋值

使用:

//无参构造构造
set<int> set1;

//迭代区间构造
vector<int> v = { 1,2,3,4,5 };
set<int> set2(v.begin(), v.end());

//拷贝构造
set<int> set3(set2);

//赋值
set<int> set4;
set4 = set3;

(3)常用迭代器接口

set迭代器是双向迭代器,只支持++或者–操作,不支持随机访问。

函数声明功能
iterator begin()返回第一个元素的迭代器
iterator end()返回最后一个元素的下一个位置的迭代器

使用:

void test02()
{
	//迭代区间构造
	vector<int> v = { 1,2,3,4,5 };
	set<int> set1(v.begin(), v.end());

	//迭代器
	//指向第一个元素的迭代器
	set<int>::iterator it1 = set1.begin();

	//指向最后一个元素的迭代器
	set<int>::iterator it2 = set1.end();

	//通过迭代器遍历
	while (it1 != it2)
	{
		cout << *it1 << " ";
		it1++;
	}
	cout << endl;
}

(4)常用插入、删除、查找接口

函数声明功能
pair<iterator,bool> insert (const value_type& val);在set中插入元素x,实际插入的是<x, x>构成的键值对,如果插入成功,返回该元素在set中的位置,true>,如果插入失败,说明x在set中已经存在,返回<x在set中的位置,false>
iterator erase (const_iterator position);删除set中position位置上的元素,返回值是一个迭代器,指向被删除元素之后的元素。如果 position 指向的是 set 中的最后一个元素,那么返回的迭代器将等于 set 的 end() 迭代器
size_type erase ( const key_type& x )删除set中值为x的元素,返回删除的元素的个数
void clear() noexcept;清空
iterator find (const value_type& val);返回set中值为x的元素的位置,找不到返回end()

使用:

//插入、删除、查找
void test03()
{
	//
	set<int> set1;

	//插入
	set1.insert(1);
	set1.insert(2);
	set1.insert(3);
	set1.insert(4);
	set1.insert(5);

	cout << "插入:";
	set<int>::iterator it1 = set1.begin();
	//通过迭代器遍历
	while (it1 != set1.end())
	{
		cout << *it1 << " ";
		it1++;
	}
	cout << endl;

	//通过迭代器遍历删除
	set<int> set2(set1);
	cout << "迭代器遍历删除:";
	set<int>::iterator it2 = set2.begin();
	//通过迭代器遍历
	while (it2 != set2.end())
	{
		it2 = set2.erase(it2);
	}
	cout << endl;
	
	cout << "键值删除:";
	set<int> set3(set1);
	set3.erase(1);
	set3.erase(3);
	set<int>::iterator it3 = set3.begin();
	//通过迭代器遍历
	while (it3 != set3.end())
	{
		cout << *it3 << " ";
		it3++;
	}
	cout << endl;

	//查找
	set<int> set4(set1);
	cout << "查找:";
	auto it4 = set4.find(2);
	if (it4 != set4.end())
		cout << *it4 << endl;
	else
		cout << "找不到!" << endl;

}

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6089873670c6404aa29357967039c526.png

(5)常用大小相关接口

函数声明功能
size_type count ( const key_type& x ) const返回set中值为x的元素的个数
bool empty() const noexcept;判断是否为空
size_type size() const noexcept;返回元素个数
使用:
void test04()
{
	vector<int> v = { 1,2,3,4,5 };
	set<int> set1(v.begin(), v.end());

	cout << "大小:" << set1.size() << endl;
	cout << "1的个数:" << set1.count(1) << endl;
	if (!set1.empty())
		cout << "不为空" << endl;
	else
		cout << "为空" << endl;
}

二、multiset

1、multiset介绍

  1. multiset是按照特定顺序存储元素的容器,其中元素是可以重复的。
  2. 在multiset中,元素的value也会识别它(因为multiset中本身存储的就是<value, value>组成 的键值对,因此value本身就是key,key就是value,类型为T). multiset元素的值不能在容器
    中进行修改(因为元素总是const的),但可以从容器中插入或删除。
  3. 在内部,multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则 进行排序。
  4. multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭 代器遍历时会得到一个有序序列。
  5. multiset底层结构为二叉搜索树(红黑树)。
    6、 multiset中的元素不能修改。

2、set与multiset区别

(1)set容器不能出现重复元素,multiset能出现重复元素。
(2)两者容器接口相同,count接口对于set来说不是1就是0,而对于multiset可以是实际元素个数,find接口对于set来说查找的元素是唯一的,而对于multiset来说查找的元素如果存在多个就返回红黑树中序遍历的第一个。

3、使用

//multiset
void test05()
{
	vector<int> v = { 1,1,3,4,5,2,4,4,4 };
	multiset<int> mset1(v.begin(), v.end());

	cout << "4的个数" << mset1.count(4)<<endl;


	multiset<int>::iterator mit = mset1.begin();
	//通过迭代器遍历
	while (mit != mset1.end())
	{
		cout << *mit << " ";
		mit++;
	}
	cout << endl;

}

三、map

1、map介绍

C++中的map容器是一种关联容器,它存储的元素是一对键值(key-value)对(使用对组pair)。每个键值对映射一个特定的键到一个特定的值。在map中,任何两个键都不能相同,因为每个键只能映射到一个值。map中的元素总是按照键的顺序排序。

2、map特征

(1)自动排序:map中的元素会根据键自动排序。默认情况下,它使用<运算符来比较键,所以键类型需要支持这个运算符。
(2)唯一键:每个键在map中必须是唯一的。
(3)直接访问:可以通过键直接访问元素。
(4)map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

3、接口使用
(1)模板参数
在这里插入图片描述

key: 键值对中key的类型
T: 键值对中value的类型
Compare:比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的 空间配置器

(1)常用构造、赋值接口

函数声明功能
map()空构造
map (const map& x);拷贝构造
map (InputIterator first, InputIterator last, const key_compare& comp = key_compare(), const allocator_type& = allocator_type());用迭代区间构造
map& operator= (map&& x);赋值

使用:

//赋值,
//构造
void test06()
{
	//迭代区间构造
	vector<pair<int, int>> v = { {1,1},{2,2},{3,3} };
	map<int,int> mp1(v.begin(), v.end());

	//空构造
	map<int, int> mp2;

	//拷贝构造
	map<int, int> mp3(mp1);

	//赋值
	map<int, int> mp4;
	mp4 = mp1;
}

(2)常用迭代器接口

map迭代器是双向迭代器,只支持++或者–操作,不支持随机访问。

函数声明功能
begin()begin:首元素的位置
end()end最后一个元素的下一个位置

使用:

迭代器
void test07()
{

	//迭代区间构造
	vector<pair<int, int>> v = { {1,1},{2,2},{3,3} };
	
	map<int, int> mp1(v.begin(), v.end());
	//迭代器遍历
	map<int, int>::iterator it = mp1.begin();
	while (it != mp1.end())
	{
		cout << it->first << " ";
		it++;
	}
	cout << endl;
}

(3)常用插入、删除、修改、查找接口

函数声明功能
pair<iterator,bool> insert ( const value_type& x )在map中插入键值对x,注意x是一个键值对,返回值也是键值对:iterator代表新插入元素的位置,bool代表释放插入成功
void erase ( iterator position )删除position位置上的元素
size_type erase ( const key_type& x )删除键值为x的元素,返回删除元素个数
void clear ( )清空
iterator find ( const key_type& x )在map中插入key为x的元素,找到返回该元素的位置的迭代器,否则返回end
mapped_type& operator[] (const key_type& k);重载[],通过key返回value的引用,不用在key是相当于插入,value会调用其默认构造进行初始化

使用:

//插入等操作
void test08()
{
	map<int, int> mp1;
	//插入pair对象
	mp1.insert({ 1,1 });
	mp1.insert({ 2,2 });
	mp1.insert({ 3,3 });
	mp1.insert({ 4,4 });
	cout << "插入后:";
	map<int, int>::iterator it1 = mp1.begin();
	while (it1 != mp1.end())
	{
		cout << it1->first << " ";
		it1++;
	}
	cout << endl;

	//通过key删除
	mp1.erase(1);

	//通过迭代器删除
	map<int, int>::iterator it2 = mp1.begin();//
	mp1.erase(it2);

	cout << "删除后:";
	map<int, int>::iterator it3 = mp1.begin();
	while (it3 != mp1.end())
	{
		cout << it3->first << " ";
		it3++;
	}
	cout << endl;

	//查找
	map<int, int>::iterator it4 = mp1.find(3);
	if (it4 != mp1.end())
		cout << "存在" << endl;
	else
		cout << "不存在" << endl;

	//通过[key]进行修改value
	mp1[3] = 1000;//修改为1000
	cout << "修改后:" << mp1[3] << endl;
}

在这里插入图片描述
(4)常用大小相关的接口

函数声明功能
size_type count ( const key_type& x ) const返回key为x的键值在map中的个数,注意map中key是唯一的,因此该函数的返回值要么为0,要么为1,因此也可以用该函数来检测一个key是否在map中
size_type size() const;返回元素个数
bool empty() const;判断是否为空

使用:

void test09()
{
	//迭代区间构造
	vector<pair<int, int>> v = { {1,1},{2,2},{3,3} };

	map<int, int> mp1(v.begin(), v.end());

	cout << "大小:" << mp1.size() << endl;
	cout << "4的个数:" << mp1.count(4) << endl;
	if (!mp1.empty())
		cout << "不为空" << endl;
	else
		cout << "为空" << endl;
}

在这里插入图片描述

四、multimap

1、multimap介绍

  1. Multimaps是关联式容器,它按照特定的顺序,存储由key和value映射成的键值对<key, value>,其中多个键值对之间的key是可以重复的。
  2. 在multimap中,通常按照key排序和惟一地标识元素,而映射的value存储与key关联的内 容。key和value的类型可能不同,通过multimap内部的成员类型value_type组合在一起,
    value_type是组合key和value的键值对: typedef pair<const Key, T> value_type;
  3. 在内部,multimap中的元素总是通过其内部比较对象,按照指定的特定严格弱排序标准对 key进行排序的。
  4. multimap通过key访问单个元素的速度通常比unordered_multimap容器慢,但是使用迭代 器直接遍历multimap中的元素可以得到关于key有序的序列。
  5. multimap在底层用二叉搜索树(红黑树)来实现。

2、map与multimap的区别

(1)multimap和map的唯一不同就是:map中的key是唯一的,而multimap中key是可以重复的。
(2)接口multimap少了 at()、[ ]重载,count(key)接口对于map来说不是1就是0,对于multimap来说还可以是多个,find(key)接口对于map来说存在唯一值,对于multimap来说如果存在多个相同的key就会返回红黑树中序遍历的第一个,其他接口基本一样。

3、使用

void test10()
{
	//迭代区间构造
	vector<pair<int, int>> v = { {1,1},{2,2},{3,3},{2,2},{2,2} };

	multimap<int, int> mp1(v.begin(), v.end());
	cout << "2的个数:" << mp1.count(2) << endl;
	//迭代器遍历
	multimap<int, int>::iterator it = mp1.begin();
	while (it != mp1.end())
	{
		cout << it->first << " ";
		it++;
	}
	cout << endl;

}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1943054.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

S02. 中断与异常处理

中断处理过程及保护 1、 中断处理过程 处理器根据中断向量号定位中断门描述符。中断向量号是中断描述符的索引&#xff0c;当处理器收到一个外部中断向量号后&#xff0c;它用此向量号在中断描述符表中查询对应的中断描述符&#xff0c;然后再去执行该中断描述符中的中断处理程…

谷歌浏览器跨域

首先创建谷歌浏览器快捷键 右击 属性 在C盘创建文件夹MyChromeDevUserData “C:\Program Files\Google\Chrome\Application\chrome.exe” --disable-web-security --user-data-dirC:\MyChromeDevUserData

数据结构初阶(C语言)-二叉树-顺序表建堆

一&#xff0c;堆的概念与结构 如果有⼀个关键码的集合&#xff0c;把它的所有元素按完全⼆叉树的顺序存储方式存储&#xff0c;在⼀个⼀维数组中&#xff0c;并满足&#xff1a;&#xff0c;i0,1,2...则称为小堆(或⼤堆)。将根结点最大的堆叫做最大堆或大根堆&#xff0c;根结…

调度子系统在特定时间执行

时序逻辑调度器设计模式允许您安排Simulink子系统在指定时间执行。以下模型说明了这种设计模式。 时序逻辑调度器图表包含以下逻辑&#xff1a; 时序逻辑调度器的关键行为 时序逻辑调度器图表包含两个状态&#xff0c;它们以不同的速率调度函数调用子系统A1、A2和A3的执行&…

frp反向代理的安装与配置、ftp服务的搭建及应用

1、frp简介 frp 是⼀个开源、简洁易⽤、⾼性能的内⽹穿透和反向代理软件&#xff0c;⽀持 tcp, udp, http, https等 协议。frp 项⽬官⽹是 https://github.com/fatedier/frp 2、frp⼯作原理 服务端运⾏&#xff0c;监听⼀个主端⼝&#xff0c;等待客户端的连接&#xff1b; …

基于内容的音乐推荐网站/基于ssm的音乐推荐系统/基于协同过滤推荐的音乐网站/基于vue的音乐平台

获取源码联系方式请查看文末&#x1f345; 摘 要 随着信息化时代的到来&#xff0c;系统管理都趋向于智能化、系统化&#xff0c;音乐推荐网站也不例外&#xff0c;但目前国内的有些公司仍然都使用人工管理&#xff0c;公司规模越来越大&#xff0c;同时信息量也越来越庞大&…

C++中const关键字的多方面应用

const 的基本作用 const有且只有一种作用&#xff0c;那就是限定被修饰的对象无法被修改&#xff0c;在c中&#xff0c;被const修饰的对象被看作常量&#xff0c;存储在只读存储区(.rodata)。 测试代码 const int a 5;char arr[a];对测试代码进行汇编编译 – gcc -S test.c …

机械学习—零基础学习日志(高数09——函数图形)

零基础为了学人工智能&#xff0c;真的开始复习高数 函数图像&#xff0c;开始新的学习&#xff01; 幂函数 利用函数的性质&#xff0c;以幂函数为例&#xff0c;因为单调性相同&#xff0c;利用图中的2和3公式&#xff0c;求最值问题&#xff0c;可以直接将式子进行简化。这…

Git之repo sync -c与repo sync -dc用法区别四十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

blender使用(四)-物体吸附与晶格形变、阵列、曲线、蒙皮修改器

1.缩放注意点 尽量不要在物体模式下缩放&#xff0c;尽量在编辑模式下缩放。 若在物体模式下做过缩放&#xff0c;右键单击物体&#xff0c;选择应用缩放 2.物体吸附及衰减 吸附&#xff1a;一个物体移动到另一个物体表面时&#xff0c;自动吸附上去 衰减&#xff1a;编辑模式下…

Nginx学习-相关概念

Nginx学习-相关概念 主要学习几个概念&#xff1a;Nginx&#xff0c;正向代理、反向代理、负载均衡、动静分离。–2020年05月29日 什么是Nginx Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务。 特点是占有内存少&…

探索未知,惊喜连连 —— 盲盒一番赏小程序,开启你的幸运之旅!

在这个充满惊喜与期待的时代&#xff0c;每一份未知都藏着无限可能。我们精心打造的“盲盒一番赏”小程序&#xff0c;正是为了满足您对惊喜的渴望&#xff0c;让每一次点击都成为一次心跳加速的旅程。 &#x1f31f; 【沉浸式体验&#xff0c;触手可及】 想象一下&#xff0c…

【源码阅读】Sony的go breaker熔断器源码探究

文章目录 背景源码分析总结 背景 在微服务时代&#xff0c;服务和服务之间调用、跨部门调用都是很常见的事&#xff0c;但这些调用都存在很多不确定因素&#xff0c;如核心服务A依赖的部门B服务挂掉了&#xff0c;那么A本身的功能将会受到直接的影响&#xff0c;而这些都会影响…

vue this.$refs 动态拼接

业务需要&#xff0c;refs是不固定的 <vxe-grid refgridWarehouse v-bind"gridWarehouseOptions" v-if"tableHeight" :height"tableHeight":expand-config"{iconOpen: vxe-icon-square-minus, iconClose: vxe-icon-square-plus}"c…

(Qt) 文件读写基础

文章目录 &#x1f5c2;️前言&#x1f4c4;ref&#x1f4c4;访问标记&#x1f5c3;️enum 标记 &#x1f5c2;️Code&#x1f4c4;demo&#x1f4c4;分点讲解&#x1f5c3;️继承体系&#x1f5c3;️打开/关闭&#x1f5c3;️写&#x1f5c3;️读 &#x1f5c2;️END&#x1f…

2024年,人工智能行业哪些证书权威?

人工智能领域颁发的证书有很多&#xff0c;但哪些更权威呢&#xff1f;看颁发证书的单位&#xff01; 工信部电子标准院的人工智能从业人员认证证书是由工业和信息化部电子工业标准化研究院&#xff08;以下简称“电子标准院”&#xff09;颁发&#xff0c;旨在评价和认证人工…

【嵌入式开发之标准I/O】文件I/O的基本概念,打开、关闭、定位函数及实例

文件I/O和标准I/O 什么是文件I/O?什么是标准I/O? 文件I/O&#xff1a;文件I/O又称系统IO&#xff0c;系统调用&#xff0c;称之为不带缓存的IO&#xff08;unbuffered I/O)。是操作系统提供的API接口函数。不带缓存指的是每个read&#xff0c;write都调用内核中的一个系统调…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(二十三)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 33 节&#xff09; P33《32.通知-进度条通知》 下载按钮对应的逻辑&#xff1a; 取消按钮对应的逻辑&#xff1a; 暂停按钮对应的…

Java | Leetcode Java题解之第274题H指数

题目&#xff1a; 题解&#xff1a; class Solution {public int hIndex(int[] citations) {int left0,rightcitations.length;int mid0,cnt0;while(left<right){// 1 防止死循环mid(leftright1)>>1;cnt0;for(int i0;i<citations.length;i){if(citations[i]>mi…

【Django】在anaconda虚拟环境中创建Django项目

文章目录 进入工作目录创建django项目及进入vscode(打开项目目录)选择解析器 进入工作目录 cd C:\WF\developer\djangodemo创建django项目及进入vscode(打开项目目录) django-admin startproject antproject选择解析器 ctrlshiftP打开命令面板