【深入C++】map和set的使用

文章目录

  • C++ 中的容器分类
    • 1. 顺序容器
    • 2. 关联容器
    • 3. 无序容器
    • 4. 容器适配器
    • 5. 字符串容器
    • 6. 特殊容器
  • set
    • 1.构造函数
    • 2.迭代器
    • 3.容量相关的成员函数
    • 4.修改器类的成员函数
    • 5.容器相关操作的成员函数
  • multiset
    • 1.equal_range
  • map
    • 1.初始化相关的函数
    • 2.迭代器
    • 3.容量相关的成员函数
    • 4.访问相关的成员函数
    • 5.修改器类的成员函数
    • 6.容器相关操作的成员函数
  • 总结

在这里插入图片描述

在这里插入图片描述

C++ 中的容器分类

在C++中,标准库提供了多种容器,这些容器可以根据其数据存储方式和功能进行分类。以下是C++中常见容器的分类:

1. 顺序容器

这些容器按顺序存储元素,适用于需要保持元素顺序的场景。

  • vector: 动态数组,支持快速随机访问和在末尾高效插入和删除操作。
  • deque: 双端队列,支持快速随机访问和在两端高效插入和删除操作。
  • list: 双向链表,支持在任何位置高效插入和删除操作,但随机访问较慢。
  • forward_list: 单向链表,只支持在头部高效插入和删除操作。
  • array: 固定大小的数组,大小在编译时确定。

2. 关联容器

这些容器根据键值对存储元素,并自动按键排序,适用于需要快速查找的场景。

  • set: 集合,存储唯一的元素,元素自动按键排序。
  • multiset: 允许重复元素的集合,元素自动按键排序。
  • map: 键值对存储的映射,键唯一且自动排序。
  • multimap: 允许重复键的映射,键自动排序。

3. 无序容器

这些容器使用哈希表存储元素,适用于需要快速查找和插入的场景,但不保证元素顺序。

  • unordered_set: 无序集合,存储唯一的元素。
  • unordered_multiset: 无序多重集合,允许重复元素。
  • unordered_map: 无序映射,键唯一。
  • unordered_multimap: 无序多重映射,允许重复键。

4. 容器适配器

这些不是独立的容器,而是对现有容器的包装,提供特定用途的接口。

  • stack: 栈,后进先出(LIFO)结构,通常使用deque或vector实现。
  • queue: 队列,先进先出(FIFO)结构,通常使用deque或list实现。
  • priority_queue: 优先队列,元素按优先级排序,通常使用vector和heap算法实现。

5. 字符串容器

  • string: 用于存储和操作字符序列,类似于动态数组,但专门针对字符。

6. 特殊容器

  • bitset: 固定大小的二进制数组,提供按位操作。

这些容器各有优缺点和适用场景,选择合适的容器可以显著提高程序的性能和可维护性。

这篇文章讲的两个容器都是关联式容器

set

在这里插入图片描述
在C++标准库中,set容器的底层实现通常是基于红黑树这种自平衡二叉搜索树。红黑树是一种能够在插入、删除和查找操作中保持对数时间复杂度的树结构。

1.构造函数

在这里插入图片描述
构造函数主要分为三个:无参构造,迭代器区间构造,拷贝构造

无参构造:

set<int> s;

迭代器区间构造:

vector<int>  v{ 1,2,3,4,5,6,7 };
set<int> s(v.begin(), v.end());

拷贝构造:

set<int> s1{ 1,2,3,4 };
set<int> s2(s1);

赋值拷贝

set<int> s1{ 1,2,3,4 };
set<int> s2;
s2 = s1;

2.迭代器

在这里插入图片描述

迭代器遍历:

auto it = s1.begin();
while (it != s1.end())
{cout << *it << ' ';it++;
}

范围for:

for (auto e : s1)
{cout << e << ' ';
}

3.容量相关的成员函数

在这里插入图片描述

int main()
{set<int> s1{ 1,2,3,4 };cout << s1.size() << endl;//4cout << s1.empty() << endl;//0return 0;
}

4.修改器类的成员函数

在这里插入图片描述
insert:
有三个重载函数
在这里插入图片描述

支持迭代器区间插入。

int main()
{set<int> s1;s1.insert(2);s1.insert(3);s1.insert(6);s1.insert(1);s1.insert(5);s1.insert(7);for (auto e : s1){cout << e << ' ';}return 0;
}

erase:
在这里插入图片描述

第二个重载函数:

int num = s1.erase(3);
cout << endl << num << endl;

删除成功返回1,删除失败返回0。

5.容器相关操作的成员函数

在这里插入图片描述
find:

int main()
{set<int> s1;s1.insert(2);s1.insert(3);s1.insert(6);s1.insert(1);s1.insert(5);s1.insert(7);auto it = s1.find(2);if (it != s1.end()) cout << *it << endl;else cout << "does not exist" << endl;return 0;
}

如果找到了返回找到的迭代器,如果没有找到则返回的是end()。
count:
count返回的是对应元素的个数:在set中存在就返回1,不存在就返回0。
在这里插入图片描述
lower_bound:

lower_bound返回的是大于等于某个数的。

int main()
{set<int> s1;s1.insert(2);s1.insert(3);s1.insert(6);s1.insert(1);s1.insert(5);s1.insert(7);auto lower = s1.lower_bound(4);cout << *lower << endl;return 0;
}

这里输出的是大于等于4的数,所以这里输出的是5。
upper_bound:

auto upper = s1.upper_bound(6);
cout << *upper << endl;

这里输出的是大于6的数,所以输出的是7。
set有一个致命的缺陷,在插入重复数据时,是插入不进去的,所以这里我们需要了解multiset。

multiset

在这里插入图片描述

multiset和set唯一不同的区别是一个支持插入重复数据,一个不支持。

int main()
{set<int> s1;s1.insert(1);s1.insert(1);s1.insert(1);s1.insert(1);for (auto e : s1) cout << e << ' ';multiset<int> s2;s2.insert(1);s2.insert(1);s2.insert(1);s2.insert(1);cout << endl;for (auto e : s2)cout << e << ' ';return 0;
}

可以set不支持插入重复数据,multiset支持插入重复数据。
在这里插入图片描述
在查找数据的时候multiset查找的是第一个数据。
删除数据:multiset删除数据,删除的是所有重复的数据,而不是删除第一个数据。

1.equal_range

int main()
{multiset<int> s{ 1,1,4,4,4,3,3,3,3,3,5,5,5, 6 };auto [a, b] = s.equal_range(3);s.erase(a, b);for (auto e : s){cout << e << ' ';}
}

equal_range可以求出指定值的范围区域,两个迭代器。
一个首一个尾。

map

在这里插入图片描述
map属于KV模型,用一个k值索引v值。
在C++标准库中,map 容器的底层实现通常是基于红黑树(Red-Black Tree)这种自平衡二叉搜索树(Self-balancing Binary Search Tree)。红黑树是一种能够在插入、删除和查找操作中保持对数时间复杂度的树结构。

1.初始化相关的函数

在这里插入图片描述

构造函数:
在这里插入图片描述
map和set的构造方式是一样的,也是三种构造函数。

2.迭代器

在这里插入图片描述
map的迭代器和set的迭代器稍有区别,但不多。

返回for:

int main()
{map<int, char> m{ { 1,'a' } ,{ 2,'b' },{ 3,'c' },{ 4,'d' },{ 5,'e' } };for (auto e : m)cout << e.first << ':' << e.second << endl;
}

迭代器区间遍历:

int main()
{map<int, char> m{ { 1,'a' } ,{ 2,'b' },{ 3,'c' },{ 4,'d' },{ 5,'e' } };auto it = m.begin();while (it != m.end()){cout << it->first << ':' << it->second << endl;it++;}
}

结构化绑定:

int main()
{map<int, char> m{ { 1,'a' } ,{ 2,'b' },{ 3,'c' },{ 4,'d' },{ 5,'e' } };for (auto [a, b] : m)cout << a << ':' << b << endl;
}

3.容量相关的成员函数

在这里插入图片描述
和set的用法大差不差。

4.访问相关的成员函数

在这里插入图片描述
operator[]:

int main()
{map<int, char> m{ { 1,'a' } ,{ 2,'b' },{ 3,'c' },{ 4,'d' },{ 5,'e' } };cout << m[1] << endl;cout << m[2] << endl;cout << m[3] << endl;
}

map可以通过一个成员的第一个键值来索引当前成员的第二个键值,就是用key索引value。
at:

int main()
{map<int, char> m{ { 1,'a' } ,{ 2,'b' },{ 3,'c' },{ 4,'d' },{ 5,'e' } };cout << m.at(1) << endl;
}

用at进行索引value。
在这里插入图片描述
可以看见如果容器当中没有当前值的索引,则会抛出异常。

5.修改器类的成员函数

在这里插入图片描述
这里修改器类的成员函数和set相同,但是insert,需要插入一个键值对:

m.insert({ 6,'f' });
m.insert(pair<int, char>(6, 'f'));
m.insert(make_pair(6, 'f'));

6.容器相关操作的成员函数

在这里插入图片描述
这些和set都是一样的。

总结

在本篇博客中,我们深入探讨了C++标准库中的mapset容器。通过详细的示例和解释,我们了解了它们的基本用法、常用操作以及在不同场景下的应用。mapset不仅为我们提供了高效的键值对存储和有序集合管理功能,还在复杂数据结构和算法设计中扮演了重要角色。

掌握mapset的使用,不仅能够提升我们的编程效率,还能帮助我们编写出更为高效和可靠的代码。在实际开发中,合理地选择和使用这些容器,可以显著优化程序的性能和可维护性。

希望通过这篇博客,大家能够对mapset有更深入的理解,并在以后的编程实践中灵活运用它们。如果你有任何疑问或建议,欢迎在评论区留言讨论。

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

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

相关文章

AVL树的理解和实现[C++]

文章目录 AVL树AVL树的规则或原理 AVL树的实现1.节点的定义2.功能和接口等的实现默认构造函数&#xff0c;析构函数拷贝构造函数插入搜索打印函数检查是否为平衡树&#xff0c;检查平衡因子旋转 AVL树 AVL树&#xff0c;全称Adelson-Velsky和Landis树&#xff0c;是一种自平衡…

Java IO模型深入解析:BIO、NIO与AIO

Java IO模型深入解析&#xff1a;BIO、NIO与AIO 一. 前言 在Java编程中&#xff0c;IO&#xff08;Input/Output&#xff09;操作是不可或缺的一部分&#xff0c;它涉及到文件读写、网络通信等方面。Java提供了多种类和API来支持这些操作。本文将从IO的基础知识讲起&#xff…

智慧职校就业管理:开启校园招聘会新模式

在智慧职校的就业管理系统中&#xff0c;校园招聘会的出现&#xff0c;为学生们提供了一个展示自我、探寻职业道路的舞台&#xff0c;同时也为企业搭建了一座直面未来之星的桥梁。这一功能&#xff0c;凭借其独特的优势与前沿的技术&#xff0c;正在重新定义校园与职场之间的过…

【JVM基础06】——组成-直接内存详解

目录 1- 引言&#xff1a;直接内存概述1-1 直接内存是什么&#xff1f;直接内存的定义(What)1-2 为什么用直接内存&#xff1f;Java程序对直接内存的使用 (Why) 2- ⭐核心&#xff1a;详解直接内存(How)2-1 文件拷贝案例介绍对比常规 IO(BIO) 和 NIO常规 IO 的操作流程NIO 的操…

LeetCode 热题 HOT 100 (009/100)【宇宙最简单版】

【图论】No. 0207 课程表【中等】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【力扣详解】谢谢你的支持&#xff01…

小公司怎么申请企业邮箱?

小公司申请企业邮箱需要考虑哪些因素&#xff1f;小公司选择企业邮箱需考虑成本、功能、安全、支持等因素。小公司怎么申请企业邮箱呢&#xff1f;注册企业邮箱需填写企业信息、选择套餐并添加用户。 一、小公司申请企业邮箱考虑的因素 1、成本效益分析 预算规划&#xff1a…

Try ubuntu core (by quqi99)

作者&#xff1a;张华 发表于&#xff1a;2024-07-20 版权声明&#xff1a;可以任意转载&#xff0c;转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明(http://blog.csdn.net/quqi99) try ubuntu core on qemu #ovmf is to ensure compatibility with the re…

matlab--legend利用for循环添加图例

第一种方法 %% 第一种方法 R 1:4; THETA1 atand(R./1.8); legend_name {}; for i 1:4THETA atand(R(i)./1.8);intTheta floor(THETA);R_THERA 1.8 - (R(i)./tand(intTheta-10:intTheta10));R_THERA1 1.8 - (R(i)/tand(intTheta));plot(R_THERA);grid on;hold onlegend…

领夹麦克风哪个品牌好,电脑麦克风哪个品牌好,热门麦克风推荐

​在信息快速传播的时代&#xff0c;直播和视频创作成为了表达与交流的重要方式。对于追求卓越声音品质的创作者而言&#xff0c;一款性能卓越的无线麦克风宛如一把利剑。接下来&#xff0c;我要为大家介绍几款备受好评的无线麦克风&#xff0c;这些都是我在实际使用中体验良好…

SpringBoot大模型流式接口

话不多说&#xff0c;直接上货 import cn.hutool.core.util.IdUtil; import com.alibaba.fastjson.JSONObject; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.Re…

人工智能(AI)在办公场所的广泛应用

人工智能&#xff08;AI&#xff09;在办公场所的广泛应用正逐步改变着我们的工作方式和效率。随着技术的进步&#xff0c;越来越多的公司和组织开始采用各种AI技术来优化工作流程、提升生产力&#xff0c;并提供更好的用户体验。以下是人工智能在办公方面的一些主要作用和影响…

LeetCode 125.验证回文串 C++写法

LeetCode 125.验证回文串 C写法 思路&#x1f914;&#xff1a; 我们不对字符串进行删除&#xff0c;这样效率太低了&#xff0c;所以可以左右开工&#xff0c;下标begin和end遇到不是字母数字字符的就跳过&#xff0c;当两边都是字母就进行比对&#xff0c;一样就继续往后走&a…

PCL 批量处理点云文件

系列文章目录 文章目录 系列文章目录前言一、PCL是什么&#xff1f;二、配置PCL环境三、使用步骤1.引入库2.主函数 总结 前言 点云处理时往往会需要对多个点云进行处理&#xff0c;比如在预处理&#xff0c;保存点云时。下面提供一个简单的点云批量转换例子&#xff0c;PCD文件…

power bi 度量值相关函数

power bi 度量值相关函数 1. 度量值的好处2. 度量值上下文3. calculate() 函数4. 度量值存储方式 1. 度量值的好处 度量值不会增加一列&#xff0c;不会修改表格度量值自带筛选功能 2. 度量值上下文 新建行和新建度量值的区别 度量值是筛选上下文&#xff1a;度量值天生具有…

机器学习 | 阿里云安全恶意程序检测

目录 一、数据探索1.1 数据说明1.2 训练集数据探索1.2.1 数据特征类型1.2.2 数据分布1.2.3 缺失值1.2.4 异常值1.2.5 标签分布探索 1.3 测试集探索1.3.1 数据信息1.3.2 缺失值1.3.3 数据分布1.3.4 异常值 1.4 数据集联合分析1.4.1 file_id 分析1.4.2 API 分析 二、特征工程与基…

SimGCL和XSimGCL

SimGCL 动机 传统的SGL(图自监督学习)使得模型可以自行发掘任务特征,解决了数据稀疏和长尾分布的问题,SGL采用节点dropout、边dropout和随机游走三种方式对图结构进行扰动(图增强)进行对比学习,可以有效提高性能 SGL主要解决传统推荐系统面临的数据稀疏和长尾分布问题。…

2024中国大学生算法设计超级联赛(1)

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;彩笔ACMer一枚。 &#x1f3c0;所属专栏&#xff1a;杭电多校集训 本文用于记录回顾总结解题思路便于加深理解。 &#x1f4e2;&#x1f4e2;&#x1f4e2;传送门 A - 循环位移解…

linux 网络子系统

__netif_receive_skb_core 是 Linux 内核网络子系统中一个非常重要的函数&#xff0c;它负责将网络设备驱动层接收到的数据包传递到上层协议栈进行处理。以下是对该函数的一些关键点的详细解析&#xff1a; 一、函数作用 __netif_receive_skb_core 函数是处理接收到的网络数据…

【简历】贵州某二本学院:JAVA秋招简历指导,简历通过率基本为0

注&#xff1a;为保证用户信息安全&#xff0c;姓名和学校等信息已经进行同层次变更&#xff0c;内容部分细节也进行了部分隐藏 简历说明 这是一份某师范学院25届二本同学的Java简历。这种就是每年都会出现的少量的完全不知道简历应该怎么写的同学。 所以这个简历&#xff0…

Java实现七大排序(一)

目录 一.插入排序 1.直接插入排序 2.希尔排序 二.选择排序 1.选择排序 2.堆排序 三.总结 一.插入排序 1.直接插入排序 直接插入排序的原理与线下玩扑克牌类似。我们拿到一张牌后要排序&#xff0c;方法就是一张一张对。直接插入排序也是这样的&#xff0c;我们得到一张…