当前位置: 首页 > ds >正文

C++map和set

目录

1.关联式和序列式容器

2.键值对 

3.树形结构的关联式容器 

3.1 set 

3.1.1 set的构造 

 3.1.2 set的修改

3.2 multiset 

3.3 map 

3.3.1 map的构造

3.3.2 map的插入操作

3.3.3 map的迭代器访问

3.3.4 operator[] :给一个key返回对应value的引用

3.4 multimap:允许冗余 


1.关联式和序列式容器

  • STL中的部分容器如:string、vector、list、deque、array、forward_list等,这 些容器统称为序列式容器,因为逻辑结构为线性序列的数据结构,两个位置存储的值之间⼀般没有紧密的关联关系,比如交换⼀下,他依旧是序列式容器。顺序容器中的元素是按他们在容器中的存储位置来顺序保存和访问的。
  • 关联式容器也是用来存储数据的,与序列式容器不同的是,关联式容器逻辑结构通常是非线性结构, 两个位置有紧密的关联关系,交换⼀下,他的存储结构就被破坏了顺序容器中的元素是按关键字来保存和访问的。关联式容器有map/set系列和unordered_map/unordered_set系列。其中存储的是<key,value>结构的键值对,在数据检索时比序列式容器效率更高。

2.键值对 

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

键值对的定义: 

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)
{}
};

3.树形结构的关联式容器 

根据应用场景的不同,STL总共实现了两种不同结构的管理式容器:树型结构与哈希结构。树型结构的关联式容器主要有四种:map、set、multimap、multiset。这四种容器的共同点是:使用平衡搜索树(即红黑树)作为其底层结果,容器中的元素是一个有序的序列

3.1 set 

  1.  set是按照一定次序存储元素的容器
  2.  在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。 set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
  3.  在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。
  4.  set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对 子集进行直接迭代。
  5.  set在底层是用二叉搜索树(红黑树)实现的。

注意:

  • 与map/multimap不同,map/multimap中存储的是真正的键值对,set中只放 value,但在底层实际存放的是由构成的键值对。
  • set中插入元素时,只需要插入value即可,不需要构造键值对。
  • set中的元素不可以重复(因此可以使用set进行去重)
  • 使用set的迭代器遍历set中的元素,可以得到有序序列
  • set中的元素默认按照小于来比较
  • set中查找某个元素,时间复杂度为:$log_2 n$
  • set中的元素不允许修改->原因:底层使用二叉搜索树进行存储,如果元素修改那么二叉树的结构会被破坏
  • set中的底层使用二叉搜索树(红黑树)来实现。

3.1.1 set的构造 

函数声明功能介绍
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的拷贝构造

 3.1.2 set的修改

函数声明功能介绍
pair<iterator,bool> insert ( const value_type& x )在set中插入元素x,实际插入的是构成的键值对,如果插入成功,返回<该元素在set中的 位置,true>,如果插入失败,说明x在set中已经存在,返回<在set中的位置,false>
void erase ( iterator first, iterator last ) 删除set中[first, last)区间中的元素

3.2 multiset 

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

注意:与set的区别就是multiset中的元素可以重复。

3.3 map 

3.3.1 map的构造

map<T,V> mp;
//T,V都表示类型

3.3.2 map的插入操作

1.有名对象

map<string,int> m;
pair<string,int> p("apple",1);
m.insert(p);

2.匿名对象

map<string,int> m;
m.insert(pair<string,int>("apple",1));

3.make_pair

map<string,int> m;
m.insert(make_pair("apple",1));

4.多参数隐式类型转换

map<string,int> m;
m.insert({"apple",1});

3.3.3 map的迭代器访问

map<string, string>::iterator it = dict.begin();
auto it = dict.begin();
while (it != dict.end())
{//cout << (*it).first <<" "<< (*it).second << endl;cout << it->first << " " << it->second << endl;//cout << it.operator->()->first << " " << it.operator->()->second << endl;//	++it;
}

注意:insert看key,若key存在则无论后序value怎么改变都不改变。(有则插入失败,无则插入成功)

3.3.4 operator[] :给一个key返回对应value的引用

V& operator[](const K& key)
{pair<iterator, bool> ret = insert({ key, V() });return ret.first->second;
}

1.pair<iterator, bool> ret = insert({ key, V() });

  • iterator:始终指向key部分(新插入的key或与key相等)
  • bool:成功 true,失败 false
  • V():缺省值

2.ret.first->second

存在两个pair——>1.insert返回值pair  2.节点KV pair

过程:

  • ret.first——>取pair中的迭代器
  • ->second——>结点指针里面的pair取value

代码示例:统计次数

	string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜",
"苹果", "香蕉", "苹果", "香蕉" };map<string, int> countMap;for (auto& e : arr){auto it = countMap.find(e);if (it == countMap.end()){countMap.insert({ e, 1 });}else{it->second++;}countMap[e]++;}map<string, int> countMap;for (auto& e : arr){countMap[e]++;}

[]相关操作:

	map<string, string> dict;// 插入dict["left"];// 插入+修改dict["right"] = "右边";// 修改dict["left"] = "左边";// 查找cout << dict["left"] << endl;

3.4 multimap:允许冗余 

注意:multimap和map的唯一不同就是:map中的key是唯一的,而multimap中key是可以 重复的。

http://www.xdnf.cn/news/3698.html

相关文章:

  • linux指令中的竖线(“|”)是干啥的?【含实例展示】
  • HTTP 状态码详解:用途与含义
  • QMK固件中LED指示灯与RGB灯详解指南
  • MySQL初阶:数据库基础,数据库和表操作,数据库中的数据类型
  • 组件通信-自定义事件
  • 基于SpringBoot+Vue实现的电影推荐平台功能一
  • SpringBoot基础(原理、项目搭建、yaml)
  • 【quantity】6 温度单位实现(temperature.rs)
  • wfp CommandParameter 详细解说
  • 数字智慧方案6190丨智慧应急综合平台解决方案(49页PPT)(文末有下载方式)
  • 开发规范-Restful
  • Android面试总结之jet pack模块化组件篇
  • GoogleTest:TEST_F
  • Proxmox VE 8.4 显卡直通完整指南:NVIDIA 2080 Ti 实战
  • 【OFDM过程中正交子载波特性的应用及全面解析】
  • C++负载均衡远程调用学习之HOOK注册机制
  • deepseek 技巧整理
  • 《Java高级编程:从原理到实战 - 进阶知识篇三》
  • 【算法应用】基于鲸鱼优化算法WOA求解VRPTW问题
  • Oracle无法正常OPEN(三)
  • ARConv的复现流程
  • btrace2.0使用方法
  • 基于FastApi实现本地部署DeepSeek-R1-Distill-Qwen与流式输出
  • 文章四《深度学习核心概念与框架入门》
  • 读书记:《认知红利》
  • 云盘系统设计
  • Vue3+Element Plus全套学习笔记-目录大纲
  • UE自动索敌插件Target System Component
  • MAAS Anvil - 高可用 MAAS 部署管理工具
  • 纳米AI搜索体验:MCP工具的实际应用测试,撰写报告 / 爬虫小红书效果惊艳