十八、map和set

news/2024/11/30 18:46:20/

文章目录

  • 一、关联式容器
    • (一)序列式容器:
    • (二)关联式容器:
  • 二、树形结构与哈希结构
    • (一)树型结构
    • (二)哈希结构
  • 三、键值对
  • 四、set
  • 五、multiset
  • 六、map
    • (一)[ ] 运算符重载
    • (二)统计次数的方式
    • (三)统计次数+排序
  • 七、multimap

一、关联式容器

(一)序列式容器:

序列式容器里面存储的是元素本身,其底层为线性序列的数据结构。比如:vector,list,deque,forward_list(C++11)等。

(二)关联式容器:

关联式容器里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高。比如:set、map、unordered_set、unordered_map等。

注意:C++STL当中的stack、queue和priority_queue属于容器适配器,它们默认使用的基础容器分别是deque、deque和vector。

二、树形结构与哈希结构

根据应用场景的不同,C++STL总共实现了两种不同结构的关联式容器:
在这里插入图片描述

(一)树型结构

树型结构容器中的元素是一个有序的序列,而哈希结构容器中的元素是一个无序的序列。

(二)哈希结构

三、键值对

键值对是用来表示具有一 一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。

比如我们若是要建立一个英译汉的字典,那么该字典中的英文单词与其对应的中文含义就是一一对应的关系,即通过单词可以找到与其对应的中文含义。

--在SGI-STL中关于键值对的定义如下:
template <class T1, class T2>
struct pair
{typedef T1 first_type;typedef T2 second_type;T1 first;T2 second;pair() : first(T1()), second(T2()){}pair(const T1& a, const T2& b) : first(a), second(b){}
};

四、set

  • set是按照一定次序存储元素的容器,使用set的迭代器遍历set中的元素,可以得到有序序列。
  • set当中存储元素的value都是唯一的,不可以重复,因此可以使用set进行去重。
  • 与map/multimap不同,map/multimap中存储的是真正的键值对<key, value>,set中只放value,但在底层实际存放的是由<value, value>构成的键值对,因此在set容器中插入元素时,只需要插入value即可,不需要构造键值对。
  • set中的元素不能被修改,因为set在底层是用二叉搜索树来实现的,若是对二叉搜索树当中某个结点的值进行了修改,那么这棵树将不再是二叉搜索树。
  • 在内部,set中的元素总是按照其内部比较对象所指示的特定严格弱排序准则进行排序。当不传入内部比较对象时,set中的元素默认按照小于来比较。
  • set容器通过key访问单个元素的速度通常比unordered_set容器慢,但set容器允许根据顺序对元素进行直接迭代。
  • set容器通过key访问单个元素的速度通常比unordered_set容器慢,但set容器允许根据顺序对元素进行直接迭代。

五、multiset

  • multiset容器与set容器的底层实现一样,都是平衡搜索树(红黑树),其次,multiset容器和set容器所提供的成员函数的接口都是基本一致的
  • multiset容器和set容器的唯一区别就是,multiset允许键值冗余,即multiset容器当中存储的元素是可以重复的

六、map

  • map是关联式容器,它按照特定的次序(按照key来比较)存储键值key和值value组成的元素,使用map的迭代器遍历map中的元素,可以得到有序序列。
  • 在map中,键值key通常用于排序和唯一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,并取别名为pair。
  • map容器中元素的键值key不能被修改,但是元素的值value可以被修改,因为map底层的二叉搜索树是根据每个元素的键值key进行构建的,而不是值value。
  • 在内部,map中的元素总是按照键值key进行比较排序的。当不传入内部比较对象时,map中元素的键值key默认按照小于来比较。
  • map容器通过键值key访问单个元素的速度通常比unordered_map容器慢,但map容器允许根据顺序对元素进行直接迭代。
  • map容器支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
  • map在底层是用平衡搜索树(红黑树)实现的,所以在map当中查找某个元素的时间复杂度为logN。

(一)[ ] 运算符重载

mapped_type& operator[] (const key_type& k);
(*((this->insert(make_pair(k, mapped_type()))).first)).second

实际上[ ]运算符重载实现的逻辑实际上就是以下三个步骤:

  • 调用insert函数插入键值对。
  • 拿出从insert函数获取到的迭代器。
  • 拿出从insert函数获取到的迭代器。
mapped_type& operator[] (const key_type& k)
{//1、调用insert函数插入键值对pair<iterator, bool> ret = insert(make_pair(k, mapped_type()));//2、拿出从insert函数获取到的迭代器iterator it = ret.first;//3、返回该迭代器位置元素的值valuereturn it->second;
}

如果k不在map中,则先插入键值对<k, V()>,然后返回该键值对中V对象的引用。
如果k已经在map中,则返回键值为k的元素对应的V对象的引用。
在这里插入图片描述

(二)统计次数的方式

	// 1、统计次数 string arr[] = { "香蕉", "苹果", "香蕉", "榴莲", "草莓", "苹果", "香蕉", "苹果","西瓜","西瓜", "香蕉", "草莓", "西瓜" };//统计次数的方式1:map<string, int> countMap;for (const auto& str : arr){// 思路:第一次出现,插入<str, 1>, 后续再出现就++次数ret->secondmap<string, int>::iterator ret = countMap.find(str);if (ret != countMap.end()){ret->second++;}else{countMap.insert(make_pair(str, 1));}}//统计次数的方式2: map<string, int> countMap;for (const auto& str : arr){// 先插入,如果str已经在map中,insert会返回str所在节点的迭代器,我们++次数即可//pair<map<string, int>::iterator, bool>  ret = countMap.insert(make_pair(str, 1));auto ret = countMap.insert(make_pair(str, 1));if (ret.second == false){ret.first->second++;}}// 统计次数方式3:map<string, int> countMap;for (const auto& str : arr){countMap[str]++;}for (const auto& e : countMap){cout << e.first << ":" << e.second << endl;}

(三)统计次数+排序

struct MapItCompare
{bool operator()(map<string, int>::iterator x, map<string, int>::iterator y){return x->second < y->second;}
};// 一、统计次数  二、找出大家最喜欢(出现次数最多)的三种水果string arr[] = { "香蕉", "苹果", "香蕉", "榴莲", "草莓", "苹果", "香蕉", "苹果", "西瓜", "西瓜", "香蕉", "草莓", "西瓜" };map<string, int> countMap;for (const auto& str : arr){countMap[str]++;}// 1. 对所有水果次数排序的思路//vector<pair<string, int>> v;vector<map<string, int>::iterator> v;map<string, int>::iterator countMapIt = countMap.begin();while (countMapIt != countMap.end()){v.push_back(countMapIt);++countMapIt;}sort(v.begin(), v.end(), MapItCompare());//自定义排序方式// 2. 利用map排序  -- 拷贝pair数据//map<int, string> sortMap;map<int, string, greater<int>> sortMap;for (auto e : countMap){sortMap.insert(make_pair(e.second, e.first));}// 3. 利用set排序  --不拷贝pair数据set<map<string, int>::iterator, MapItCompare> sortSet;countMapIt = countMap.begin();while (countMapIt != countMap.end()){sortSet.insert(countMapIt);++countMapIt;}//4.优先级队列typedef map<string, int>::iterator M_IT;priority_queue<M_IT, vector<M_IT>, MapItCompare> pq;countMapIt = countMap.begin();while (countMapIt != countMap.end()){pq.push(countMapIt);++countMapIt;}
}

七、multimap

  • multimap容器与map容器的底层实现一样,也都是平衡搜索树(红黑树),其次,multimap容器和map容器所提供的成员函数的接口都是基本一致的
  • multimap容器和map容器的区别与multiset容器和set容器的区别一样,multimap允许键值冗余,即multimap容器当中存储的元素是可以重复的。
  • 由于multimap容器允许键值冗余,调用[ ]运算符重载函数时,应该返回键值为key的哪一个元素的value的引用存在歧义,因此在multimap容器当中没有实现[ ]运算符重载函数。

http://www.ppmy.cn/news/88885.html

相关文章

11省政企单位密集调研实在智能数字员工

当前&#xff0c;数字中国建设迎来前所未有的发展机遇。五月&#xff0c;“数字中国”建设持续如火如荼&#xff0c;实在智能又迎来了新的“考察团路线”&#xff1a;西部新宁甘云中轴线晋豫鄂湘东部鲁苏闽&#xff0c;来自11省&#xff0c;20余个“数字化改革政企考察团”&…

2023年湖北助理工程师个人申报怎么申请?

这是许多出入职场的人&#xff0c;比较关心的话题&#xff0c;想要申请一个助理工程师怎么办呢&#xff1f;助理职称好不好办&#xff1f;助理工程师职称个人怎么申请呢&#xff1f;助理工程师申需要什么材料呢&#xff1f;助理工程师申报有什么流程呢&#xff1f;甘建二现在教…

代码随想录算法训练营第52天 |300、674、718

300. 最长递增子序列 题目描述 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6,2…

第三方实验室云LIS系统

本套云LIS系统基于B/S架构的实验室管理系统&#xff0c;整个系统的运行基于WEB层面&#xff0c;只需要在对应的工作台安装一个浏览器软件有外网即可访问。SaaS服务&#xff0c;无需部署&#xff0c;开通账号接口快速入门使用&#xff0c;集齐前处理、检验、报告、质控、统计分析…

【Go语言从入门到实战】面向对象编程篇

面向对象编程 Go语言的面向对象编程和其他语言有非常大的差别。 Go 是一种面向对象的语言吗&#xff1f; 是和不是。虽然 Go 有类型和方法&#xff0c;并允许面向对象的编程风格&#xff0c;但没有类型层次结构&#xff08;继承&#xff09;。Go 中的“接口”概念提供了一种不…

互联网医院系统的优势与挑战:现状调研分析

随着互联网技术的不断发展和普及&#xff0c;互联网医院系统也逐渐走进人们的视野。这种以互联网技术为支撑的医疗服务模式&#xff0c;可以为患者提供更加便捷、快速和高效的医疗服务&#xff0c;同时也可以缓解医院资源短缺的问题。 一、互联网医院系统的优势 方便快捷 互联…

linuxOPS基础_linux安装配置

Linux系统下载 Linux系统版本选择&#xff1a;CentOS7.6 x64&#xff0c;【镜像一般都是CentOS*.iso文件】 问题&#xff1a;为什么不选择最新版的8 版本&#xff1f; 7.x 目前依然是主流 7.x 的各种系统操作模式是基础 官网&#xff1a;https://www.centos.org/ &#xff0c;…

Day6 高级别测试——功能测试、系统测试、能力测试、容量测试、强度测试、易用性测试、安全性测试、性能测试、存储测试

Day6 高级别测试——功能测试、系统测试、能力测试、容量测试、强度测试、易用性测试 文章目录 Day6 高级别测试——功能测试、系统测试、能力测试、容量测试、强度测试、易用性测试软件产品开发周期的模型功能测试(Function Testing)系统测试(System Testing)能力测试(Facilit…