Set和Map

一、Set的介绍

1.1、Set相关文档介绍

cplusplus.com/reference/set/set/?kw=set 

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

1. 与map/multimap不同,map/multimap中存储的是真正的键值对<key, value>,set中只放
value,但在底层实际存放的是由<value, value>构成的键值对。
2. set中插入元素时,只需要插入value即可,不需要构造键值对。
3. set中的元素不可以重复(因此可以使用set进行去重)。
4. 使用set的迭代器遍历set中的元素,可以得到有序序列
5. set中的元素默认按照小于来比较(升序)
6. set中查找某个元素,时间复杂度为:log2 
7. set中的元素不允许修改
8. set中的底层使用二叉搜索树(红黑树)来实现

1.2、Set的使用

既然set是容器,那他也可以像前几个一样被构造。头文件#include<set>

1.空构造和拷贝构造
        set<int> s1;
        set<int> s2(s1);
2.迭代器构造
        string s3("I love C++");
        set<char> s4(s.begin(), s.end());
3.大于比较
        set的底层是搜素二叉树,默认是小于排序(升序),也可是调成大于排序(降序)。

        set<int, greater<int>> s5;

迭代器接口:

容量接口:

修改接口:

这里我们对Set进行一些测试:

#include<iostream>
#include<set>
using namespace std;
 
void test1()
{
	set<int> s1;
	s1.insert(1);   //插入操作
	s1.insert(3);
	s1.insert(5);
	s1.insert(7);
	s1.insert(4);
    s1.insert(4);
    s1.insert(5);
    s1.insert(1);
	set<int> s2(s1);
	set<int>::iterator it = s1.begin();
	for (auto e : s1)
	{
		cout << e << " ";   //  1 3 4 5 7,是升序排列,别搞错了
	}
	cout << endl;
	set<int>::iterator pos1 = find(s1.begin(), s1.end(), 5);
	set<int>::iterator pos2 = s1.find(7);   //set自带的查找函数
	if (it != s1.end())
	{
		s1.erase(pos1);   //删除5
		s1.erase(pos2);
		s1.insert(10);
		s1.insert(20);
	}
	while (it != s1.end())
	{
		cout << *it << " ";    //1 3 4 10 20
		*it++;
	}
	cout << endl;
	//删除指定区间
	set<int>::iterator ret = s2.find(5);
	s2.erase(s2.begin(), ret);
	for (auto e : s2)
	{
		cout << e << " ";   //5 7
	}
	cout << endl;
  //寻找是否有val,找到返回1
	if (s2.count(5)) // s2中有5就返回1,进入循环
	{
		cout << "s2中有5:" << endl;  //s2中有5
	}
	cout << s2.empty() << endl;  // 判空
	cout << s1.size() << endl;   //s1的个数是5
	cout << s2.size() << endl;   //s2的个数是2
}
 
int main()
{
	test1();
}

二、multiset 的介绍

2.1、multiset相关文档介绍

cplusplus.com/reference/set/multiset/?kw=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底层结构为二叉搜索树(红黑树)。

注意:

1. multiset中再底层中存储的是<value, value>的键值对
2. mtltiset的插入接口中只需要插入即可
3. 与set的区别是,multiset中的元素可以重复,set是中value是唯一的
4. 使用迭代器对multiset中的元素进行遍历,可以得到有序的序列
5. multiset中的元素不能修改
6. 在multiset中找某个元素,时间复杂度为O(log2)
7. multiset的作用:可以对元素进行排序

2.2、multiset的使用

 multiset的count和erase跟set相比有很大区别:

1、set.count(val)是如果找到val就返回1;因为multiset的数可以重复,multiset.count(val)找到val后返回multiset中有几个val。
2、set.erase(val)是找到要删除的val后,返回1;multiset.erase(val)找到要删除的val后返回val有几个,并且全删val。

这里我们对multiset进行一些测试:

void test2()
{
	multiset<int> multiset;
	multiset.insert(4);
	multiset.insert(5);
	multiset.insert(2);
	multiset.insert(1);
	multiset.insert(1);
	multiset.insert(3);
	multiset.insert(3);
	multiset.insert(3);
	for (auto e : multiset)
	{
		cout << e << " ";   
	}
	cout << endl;
	set<int> set(multiset.begin(), multiset.end());
	
 
	cout << multiset.erase(1) << endl;//2 返回删除的1的个数
	for (auto e : multiset)
	{
		cout << e << " ";  //2 3 3 3 4 5
	}
	cout << endl;
	cout << set.erase(4) << endl;//1 返回一个bool值,存在删除的值返回1
	for (auto e : multiset)
	{
		cout << e << " ";  //2 3 3 3 4 5
	}
	cout << endl;
	auto pos1 = multiset.find(3); //返回中序的第一个3的迭代器
	while (pos1 != multiset.end())
	{
		cout << *pos1 << " ";//3 3 3 4 5
		pos1++;
	}
}

三、Map的介绍

3.1、Map相关文档介绍

cplusplus.com/reference/map/map/?kw=map

1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元
素。
2. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的
内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型
value_type绑定在一起,为其取别名称为pair:
typedef pair<const key, T> value_type;
3. 在内部,map中的元素总是按照键值key进行比较排序的。
4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序
对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
5. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树 ))

3.2、Map的使用

#include<iostream>
#include<map>
using namespace std;
 
int main()
{
    map<string, int> m;//创建一个map对象m
	//向m中插入pair
 
	map<string, int> m1(m.begin(), m.end);//用m的区间构造m1
	map<string, int> m2(m1);//用m1拷贝构造m2
 
	return 0;
}
key: 键值对中key的类型
T: 键值对中value的类型
Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比
较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户
自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的
空间配置器
注意:在使用map时,需要包含头文件#include<map>
map的迭代器
map的容量与元素访问
        
注意:在元素访问时,有一个与operator[ ]类似的操作at()(该函数不常用)函数,都是通过
key找到与key对应的value然后返回其引用,不同的是:当key不存在时,operator[ ]用默认
value与key构造键值对然后插入,返回该默认value,at()函数直接抛异常。
map中元素的修改
map的key不允许被修改。
map中元素的查找
map可以用[ ]进行访问(不是下标访问,一定要注意)
mapped_type& operator[] (const key_type& k);

具体实现如下:

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

这个如果不好理解的话,看一下下面这个:

mapped_type& operator[] (const key_type& k)
{
    //1、调用insert返回迭代器区间
	pair<iterator, bool> ret = insert(make_pair(k, mapped_type()));
    //2、利用ret调用value值
	return ret.first->second;//return (*(ret.first)).second;
}
  • 首先调用insert函数插入键值对返回迭代器ret
  • 通过返回的迭代器ret调用元素值value。

在这里我们又分两种情况去处理:

1、如果k在map对象中,则插入失败,返回的bool类型为false,返回的迭代器为k所在结点的迭代器,而迭代器解引用*(ret.first)获得的就是pair,最后再通过pair访问到value值,整体可优化成ret.first->second,这里返回引用的好处为查找k对应v,修改k对应v。


2、如果k不在map对象中,则插入成功,返回的bool类型为true,返回的迭代器为新插入的k所在结点的迭代器位置,接着调用ret.first获得pair的迭代器,再通过->second获得value,这里返回引用的好处为插入和修改。

对Map的测试:
void test_map1()
{
	map<string, string> dict;
	//dict.insert(pair<string, string>("sort", "排序"));
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("string", "字符串"));
	dict.insert(make_pair("count", "计数"));

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

void test_map2()
{
	map<string, string> dict;
	//dict.insert(pair<string, string>("sort", "排序"));
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("string", "字符串"));
	dict.insert(make_pair("count", "计数"));
	dict.insert(make_pair("string", "(字符串)")); // 插入失败

	dict["left"];			// 插入
	dict["right"] = "右边"; // 插入+修改
	dict["string"] = "(字符串)"; // 修改
	cout << dict["string"] << endl; // 查找
	cout << dict["string"] << endl; // 查找


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

		++dit;
	}
	cout << endl;
}

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

	for (auto& e : arr)
	{
		countMap[e]++;
	}

	for (auto& kv : countMap)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
}

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

int main()
{
	test_map1();
    test_map2();
    test_map3();
	return 0;
}
【总结】
1. map中的的元素是键值对
2. map中的key是唯一的,并且不能修改
3. 默认按照小于的方式对key进行比较
4. map中的元素如果用迭代器去遍历,可以得到一个有序的序列
5. map的底层为平衡搜索树(红黑树),查找效率比较高O(log2)
6. 支持[]操作符,operator[]中实际进行插入查找。

四、multiset的介绍

4.1、multiset相关文档介绍

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在底层用二叉搜索树(红黑树)来实现。
注意: multimap和map的唯一不同就是:map中的key是唯一的,而multimap中key是可以
重复的

4.2、multimap的使用

1、map中的valuevalue是唯一的,不允许重复。multimap可以。

2、multimap中没有[ ]。因为它的key和value是一对多的关系,比如上面的苹果,那key是苹果,但是苹果出现了好几次,每一个都有一个value,那他到底返回哪一个呢?为啥map能返回呢,因为在map中每一个key(苹果)都对应一个自己的value,所以每次返回一个value.但是multimap是一个key有好几个value.

multimap测试:
void test7()
{
	multimap<string, string> mlp1;
	mlp1.insert(make_pair("one", "一"));
	mlp1.insert(make_pair("two", "二"));
	mlp1.insert(make_pair("three", "三"));
	mlp1.insert(make_pair("four", "四"));
    mlp1.insert(make_pair("four", "四"));
	mlp1.insert(make_pair("spring", "五"));
    mlp1.insert(make_pair("spring", "五"));
 
	for (auto e : mlp1)
	{
		cout << e.first << ":" << e.second << endl;
	}
}
int main()
{
	test7();
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

iOS14 Widget 小组件调研

桌面小组件是iOS14推出的一种新的桌面内容展现形式。 根据苹果的统计数据&#xff0c;“一般用户每天进入主屏幕的次数超过90次”&#xff0c;如果有一个我们应用的小组件在桌面&#xff0c;每天都有超过90次曝光在用户眼前的机会&#xff0c;这绝对是一个顶级的流量入口。 “…

世邦通信 SPON IP网络对讲广播系统uploadjson.php任意文件上传漏洞

产品介绍 世邦通信SPON IP网络对讲广播系统采用领先的IPAudio™技术,将音频信号以数据包形式在局域网和广域网上进行传送,是一套纯数字传输系统。 漏洞描述 spon IP网络对讲广播系统uploadjson.php存在任意文件上传漏洞&#xff0c;攻击者可以通过构造特殊请求包上传恶意后门…

【NLP】多标签分类【上】

简介 《【NLP】多标签分类》主要介绍利用三种机器学习方法和一种序列生成方法来解决多标签分类问题&#xff08;包含实验与对应代码&#xff09;。共分为上下两篇&#xff0c;上篇聚焦三种机器学习方法&#xff0c;分别是&#xff1a;Binary Relevance (BR)、Classifier Chain…

python 爬虫 request get或post传参

爬虫传参 import requestsurl http://www.xxx# get 或 post 传参数据 data {"pageNo": 1652,"pageSize": 10, }headers {Cookie: ,Host: ,Origin: ,Referer: ,User-Agent: , }# get 请求 # res requests.get( # url, # paramsdata, # hea…

PINN物理信息网络 | 泊松方程的物理信息神经网络PINN解法

基本介绍 泊松方程是一种常见的偏微分方程&#xff0c;它在物理学和工程学中具有广泛的应用。它描述了在某个区域内的标量场的分布与该场在该区域边界上的值之间的关系。 物理信息神经网络&#xff08;PINN&#xff09;是一种结合了物理定律和神经网络的方法&#xff0c;用于…

机器学习---流形学习

1. 流形学习 作为机器学习研究的热点问题之一&#xff0c;流形学习是要从高维数据集中发现内在的低维流形&#xff0c;并基于低 维流形来实现随后的各种机器学习任务&#xff0c;如模式识别&#xff0c;聚类分析。与欧氏空间不同&#xff0c;流形学习主要 处理的是非欧空间里…

spark基础--学习笔记

1 spark 介绍 1.1 spark概念 Apache Spark是专为大规模数据处理而设计的快速通用的分布式计算引擎&#xff0c;是开源的类Hadoop MapReduce的通用分布式计算框架。和MapReduce一样&#xff0c;都是完成大规模数据的计算处理。 简而言之&#xff0c;Spark 借鉴了 MapReduce思…

Mysql是怎么运行的(上)

文章目录 Mysql是怎么运行的Mysql处理一条语句的流程连接管理解析与优化存储引擎 基本配置配置文件系统变量状态变量字符集四种重要的字符集MySQL中的utf8和utf8mb4各级别的字符集和比较规则MySQL中字符集的转换排序规则产生的不同的排序结果 InnoDB存储引擎介绍COMPACT行格式介…

06.构建大型语言模型步骤

在本章中,我们为理解LLMs奠定了基础。在本书的其余部分,我们将从头开始编写一个代码。我们将以 GPT 背后的基本思想为蓝图,分三个阶段解决这个问题,如图 1.9 所示。 图 1.9 本书中介绍的构建LLMs阶段包括实现LLM架构和数据准备过程、预训练以创建基础模型,以及微调基础模…

HarmonyOS应用开发学习笔记 UI布局学习 List(){}创建列表 列表形式显示 简单使用

List 创建列表 列表形式显示 官方文档&#xff1a;创建列表&#xff08;List&#xff09; 关键代码 List(){} 列表控件ListItem() {} 子元素 例如 1、简单使用代码 List(){} List() {ListItem() {Row() {Image($r(app.media.iconE)).width(40).height(40).margin(10)Tex…

继承详细说明

概述 Java中提供一个关键字extends&#xff0c;用这个关键字&#xff0c;我们可以让一个类和另一个类建立起父子关系。 例如&#xff1a;public class Student extends People {} Student称为子类&#xff08;派生类&#xff09;&#xff0c;People称为父类(基类 或超类)。 …

分布式系统架构设计之分布式消息队列 VS 分布式事务

1、分布式事务的挑战 在分布式系统中&#xff0c;事务的处理变得尤为复杂&#xff0c;传统的数据库事务&#xff08;ACID&#xff09;在单一数据库中可以确保数据的完整性和一致性&#xff0c;但在多个分布式节点间保证事务的原子性、一致性、隔离性和持久性变得极具挑战性。 …

【Go】excelize库实现excel导入导出封装(三),基于excel模板导出excel

前言 大家好&#xff0c;这里是符华~ 关于excelize库实现excel导入导出封装&#xff0c;我已经写了两篇了&#xff0c;我想要的功能基本已经实现了&#xff0c;现在还差一个模板导出&#xff0c;这篇文章就来讲讲如何实现用模板导出excel。 前两篇&#xff1a; 【Go】excel…

作业:通过两台linux主机配置ssh实现互相免密登陆

做题步骤&#xff1a; 一.开启两个Linux主机&#xff0c;并且用ssh连接&#xff0c;要能够ping通 我这里是server&#xff1a;192.168.81.129 client&#xff1a;192.168.81.130 举例 步骤&#xff1a; 1.安装服务软件 2.运行软件程序 3.根据自定配置提供对应的服务/etc/chr…

02.构建和使用的大型语言模型(LLMs)阶段

我们为什么要建立自己的LLMs?LLM从头开始编码是了解其机制和局限性的绝佳练习。此外,它还为我们提供了必要的知识,可以保留或微调现有的开源LLM架构,以适应我们自己的特定领域的数据集或任务。 研究表明,在建模性能方面,定制(LLMs为特定任务或领域量身定制的)可以胜过…

如何高效阅读Linux的man page

有时候需要在man page中查某个命令的用法&#xff0c;我们一般会使用man command的方式来查询&#xff0c;例如man vmstat.但是对于一些bash内置的命令&#xff0c;如alias,如果使用man alias会打开General Commands Manual ,如下图 可以看到&#xff0c;内置命令很多&#xff…

如何通过 Prompt 优化大模型 Text2SQL 的效果

前言 在上篇文章中「大模型LLM在Text2SQL上的应用实践」介绍了基于SQLDatabaseChain的Text2SQL实践&#xff0c;但对于逻辑复杂的查询在稳定性、可靠性、安全性方面可能无法达到预期&#xff0c;比如输出幻觉、数据安全、用户输入错误等问题。 本文将从以下4个方面探讨通过Pr…

用于生成信息提取的大型语言模型综述

论文地址&#xff1a;https://arxiv.org/pdf/2312.17617.pdf 代码仓库&#xff1a;https://github.com/quqxui/Awesome-LLM4IE-Papers 信息抽取&#xff08;IE&#xff09;旨在从纯自然语言文本中提取结构化知识&#xff08;如实体、关系和事件&#xff09;。最近&#xff0c…

初识 Elasticsearch 应用知识,一文读懂 Elasticsearch 知识文集(2)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

手拉手springboot3整合mybatis-plus多数据源

环境介绍 技术栈 springbootmybatis-plusmysql 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 17 Spring Boot 3.1.7 dynamic-datasource 3.6.1 mybatis-plus 3.5.3.2 加入依赖 <dependency><groupId>com.baomidou</groupId><arti…