C++:map&&set的简单使用

2023-11-12

关联式容器

在初期我们接触到的vector、list、deque、queue等,这些容器都称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。那什么是关联式容器?它与序列式容器有什么区别?

关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高

键值对

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。
就好比一个单词对应的他应有的一个中文意思,这种一 一对应的关系,就是KV值关系
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)
{}
};

树形结构的关联式容器

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

set

文档介绍

可以通过文档提取重要的一下几点:

1.set存储的value值不能重复,所以可以用set进行去重
2.set存储的value值不能修改,因为value被const修饰,修改value值可能会破坏树结构(但可以删除或插入节点)
3.set中的value以弱排序的顺序进行存储,set默认弱排序是小于
4.与map/multimap不同,set只存储value而不是<key, value>的键值对,但set的底层是由<value, value>这样的键值对实现,所以插入数据不用构造键值对
5.用set的迭代器遍历容器,得到的是有序数列
6.set查找某个元素的时间复杂度为O(logN)

先来看第一点:
可以通过insert这个函数接口来证明:

在这里插入图片描述

#include<iostream>
#include<set>

using namespace std;

int main()
{
	set<int> Set;
	Set.insert(1);
	cout << Set.insert(1).second << endl;;
	
	return 0;
}

可以观察第一条的insert的返回值是pair<iterator, bool>,我们可以通过重复插入相同的值,并获取第二次插入的返回值的第二个参数

结果:
在这里插入图片描述
可以发现打印出的是0, 说明插入失败false!

第二点:
在这里插入图片描述
有没有发现不管是迭代器是const类型的 还是不是const类型的迭代器其实都是const_iterator来实现的,改不了set中储存的value值,其实要想若是能随意更改的话,其底层结构也不存在了。

第三点:

在这里插入图片描述

set(constructor)中:
在这里插入图片描述

第五点:

#include<iostream>
#include<set>

using namespace std;

int main()
{
	set<int> Set;
	Set.insert(2);
	Set.insert(1);
	Set.insert(3);
	Set.insert(5);
	Set.insert(6);
	Set.insert(9);
	Set.insert(8);

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

	return 0;
}

在这里插入图片描述
其实底层就是通过平衡二叉树中序遍历出的有序元素数列

find与count

在这里插入图片描述
在set中find一般都用来判断val是否在set实例化对象中
在这里插入图片描述
而没找到返回的是对象的end();

#include<iostream>
#include<set>

using namespace std;

int main()
{
	set<int> Set;
	Set.insert(2);
	Set.insert(1);
	Set.insert(3);


	auto it1 = Set.find(2);
	auto it2 = Set.find(4);
	if (it1 != Set.end())
		cout << 2 << " " << "在" << endl;
	else
		cout << 2 << " " << "不在" << endl;

	if (it2 != Set.end())
		cout << 4 << " " << "在" << endl;
	else
		cout << 4 << " " << "不在" << endl;

	return 0;
}

在这里插入图片描述

  • 其实在set中有还有个函数count它比find更实用,而又因为set中的value的值是不能变的,所以count只有1或0,也意味着在或不在
    在这里插入图片描述
    在这里插入图片描述
#include<iostream>
#include<set>

using namespace std;

int main()
{
	set<int> Set;
	Set.insert(2);
	Set.insert(1);
	Set.insert(3);

	if (Set.count(2))
		cout << 2 << " " << "在" << endl;
	else
		cout << 2 << " " << "不在" << endl;

	if (Set.count(4))
		cout << 4 << " " << "在" << endl;
	else
		cout << 4 << " " << "不在" << endl;

	return 0;
}

在这里插入图片描述
结果都是一样的
但是代码逻辑会更简单一点

multiset

multi-:在这里插入图片描述
其意义就是set中的value所对应的关系可以是多个

#include<iostream>
#include<set>

using namespace std;

int main()
{
	multiset<int> multi_Set;
	multi_Set.insert(2);
	multi_Set.insert(2);
	multi_Set.insert(2);
	multi_Set.insert(1);
	multi_Set.insert(1);
	multi_Set.insert(1);
	multi_Set.insert(3);
	multi_Set.insert(3);

	for (auto& num : multi_Set)
	{
		cout << num << " ";
	}


	return 0;
}

在这里插入图片描述
multiset跟set没什么大区别,需要注意的是multiset中的find返回的iterator实际是中序的第一个

int main()
{
	multiset<int> multi_Set;
	multi_Set.insert(2);
	multi_Set.insert(2);
	multi_Set.insert(2);
	multi_Set.insert(1);
	multi_Set.insert(1);
	multi_Set.insert(1);
	multi_Set.insert(3);
	multi_Set.insert(3);

	auto it = multi_Set.find(1);
	while (it != multi_Set.end() && *it == 1)
	{
		cout << *it << " ";
		it++;
	}

	return 0;
}

在这里插入图片描述

map

在这里插入图片描述
前面的set存的是value,而map存的是键值对

map<string, int> m; //创建一个对象
m.insert(make_pair("hello", 1));
m.insert(pair<string, int>("world", 2));

上面用了两种方式插入,make_pair其实封装了pair<>的调用函数
在这里插入图片描述
在这里插入图片描述
map存储的值是键值对,pair<T1,T2>中的T1类型变量是const,T2类型的变量可以更改
在这里插入图片描述
map存储比较规则:
在这里插入图片描述
可以知道mapped_type不会参与比较,仅仅只有Key(key_type)

用map就可以统计字符串的次数

void test()
{
	string arr[] = { "香蕉","梨子", "芒果",
					"草莓", "苹果", "苹果",
					"西瓜", "苹果", "香蕉",
					"苹果", "香蕉" };
	map<string, int> Map;
	for (auto& str : arr)
	{
		auto it = Map.find(str); // 在map中查找字符串
		if (it != Map.end()) // map中有这个键值对
		{
			it->second++;
		}
		else
		{
			Map.insert(make_pair(str, 1));
		}
	}

	for (auto kv : count)
	{
		cout << kv.first << ':' << kv.second << endl;
	}
}

在这里插入图片描述
这里count此时就能发挥作用统计次数了

在这里插入图片描述

void test()
{
	string arr[] = { "香蕉","梨子", "芒果",
					"草莓", "苹果", "苹果",
					"西瓜", "苹果", "香蕉",
					"苹果", "香蕉" };
	map<string, int> Map;
	for (auto& str : arr)
	{
		Map[str]++;
	}

	for (auto kv : Map)
	{
		cout << kv.first << ':' << kv.second << endl;
	}
}

效果跟上面的一样

在这里插入图片描述
[]的原理:
在这里插入图片描述
简化一下

auto ret = insert(make_pair(k, mapped_type()); 
//ret类型是pair<iterator, bool>
return ret.first->second; //-> (这里返回的是iterator->second的引用)

multimap

multimap与map就像multiset与set一样,但是multimap没有map的operator[]重载

void test()
{
	string arr[] = { "香蕉","梨子", "芒果",
					"草莓", "苹果", "苹果" };
	multimap<string, int> multi_Map;
	for (auto& str : arr)
	{
		multi_Map.insert(make_pair(str, 1));
	}

	for (auto kv : multi_Map)
	{
		cout << kv.first << ':' << kv.second << endl;
	}
}

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++:map&&set的简单使用 的相关文章

随机推荐

  • 【带头结点的单链表】

    带头结点的单链表 前言 一 带头结点的单链表结构体设计 1 带头结点的单链表 2 结构体声明 二 函数实现 1 初始化 2 申请新节点 3 头插 4 尾插 5 按位置插入 6 头删 7 尾删 8 销毁 总结 前言 单链表的概念 单链表是一种
  • CS162 操作系统HW2(使用Liunx内核链表以及多线程实现WordCounter)

    心得体会 IDE自动提示补全真的特别重要 大大提高开发效率 通过IDE自动搜索库函数API GDB调试能力要加强 使用前面提供的list h来改写wordCount程序 头文件的实现相当有技巧 将使用外部list库 多线程都用宏定义到同一份
  • Could not load dynamic library ‘libcupti.so.10.0‘; dlerror: libcupti.so.10.0...

    环境 Ubuntu 16 04 CUDA 10 0 CUDNN 7 6 5 nvcc NVIDIA R Cuda compiler driver Copyright c 2005 2018 NVIDIA Corporation Built
  • ESP32 /ESP8266在VS Code and PlatformIO上传文件系统 (SPIFFS)

    ESP32 ESP8266在VS Code and PlatformIO上传文件系统 SPIFFS 学习如何上传文件到ESP32板文件系统 SPIFFS 使用VS Code与PlatformIO IDE扩展 快速和简单 使用ESP32的文件
  • 【计算机毕业设计】课堂考勤微信小程序 基于微信小程序的课堂考勤管理系统

    毕设帮助 源码交流 技术解答 见文末 一 前言 在目前国内的高校课堂考勤中 传统的到场点名方式耗费了教师大量的时间和精力 随着课堂人数的增加 学生群体呈现多样性 这种点名考勤方式将不再适合日常使用 而且传统的点名考勤无法避免代人答到现象 极
  • 包装类这颗语法糖,其实并不甜

    历史文章推荐 你真的了解时间吗 细数ThreadLocal三大坑 内存泄露仅是小儿科 Java 8 ConcurrentHashMap源码中竟然隐藏着两个BUG ConcurrentHashMap中有十个提升性能的细节 你都知道吗 Hash
  • 2023年及以后语言、视觉和生成模型的发展和展望

    一 简述 在过去的十年里 研究人员都在追求类似的愿景 帮助人们更好地了解周围的世界 并帮助人们更好地了解周围的世界 把事情做完 我们希望建造功能更强大的机器 与人们合作完成各种各样的任务 各种任务 复杂的信息搜寻任务 创造性任务 例如创作音
  • 如何在jieba分词中加自定义词典_R-数据挖掘

    一 jiebaR主要函数 1 worker 加载jiebaR库的分词引擎 worker type mix dict DICTPATH hmm HMMPATH user USERPATH idf IDFPATH stop word STOPP
  • 少儿编程竞赛概览

    少儿编程竞赛概览 全国性竞赛活动名单的确定 最终确定的 29 项中的信息类竞赛 学编程的孩子可以报哪些比赛 CSP J S 计算机非专业组别能力认证 全国中小学生创 造大赛 蓝桥杯青少年创意编程比赛 全国青少年编程创意与智能设计大赛 全国中
  • Ubuntu系统操作指令详解

    Ubuntu系统操作指令详解 解压文件指令 vim使用指令 1 进入编辑模式 2 退出编辑模式 ls alh显示出来内容的意思 创建文件夹 创建文件 删除当前文件夹下所有文件 ubuntu删除命令记录的方法 Ubuntu中复制文件出现权限不
  • 从malloc中窥探Linux内存分配策略

    malloc函数是C C 中常用内存分配库函数 本篇文章将以Linux平台上的malloc为剖析对象 深入了解分配一块内存的旅程 malloc入门 使用malloc 需要包含头文件 stdlib h 函数原型如下 extern void m
  • utf8和utf8mb4的区别

    一 简介 MySQL在5 5 3之后增加了这个utf8mb4的编码 mb4就是most bytes 4的意思 专门用来兼容四字节的unicode 好在utf8mb4是utf8的超集 除了将编码改为utf8mb4外不需要做其他转换 当然 为了
  • c#之string和stringBuilder

    C String与StringBuilder 转载 1 什么时候用String 什么时候用StringBuilder 字符串一旦创建就不可修改大小 所以对字符串添加或删除操作比较频繁的话 那就不要用String而用StringBuilder
  • 【java8的特性-4】日期时间!

    一 获取当前时间 Java 8提供了三个主要的类来处理日期和时间 LocalDate LocalTime和LocalDateTime 以下是这些类的简要说明 LocalDate 代表一个日期 它包含了年 月 日等信息 但没有时间信息 Loc
  • 第四章:SQL Server2019数据库 之 综合案例练习、 使用SQL语句插入数据、更新和删除数据

    目录 一 综合案例 数据表的基本操作 二 插入数据 1 插入单行数据 2 插入多行数据 3 表中数据的复制 三 更新和删除数据 1 UPDATE 语句 2 DELETE 语句 学前必备知识 第一章 SQL Server 数据库环境搭建与使用
  • Linux 系统sudo apt-get update出错E: Problem executing scripts APT::Update::Post-Invoke-Success

    Ubuntu系统运行 sudo apt get update时报错如下 E Problem executing scripts APT Update Post Invoke Success if usr bin test w var cac
  • Java安全入门(二)——CC链1 分析+详解

    组件介绍 Apache Commons 当中有 个组件叫做 Apache Commons Collections 主要封装了Java 的 Collection 集合 相关类对象 它提供了很多强有 的数据结构类型并且实现了各种集合工具类 作为
  • 禁用Android切换动画

    禁用Android切换动画 前言 最近有个功能要禁用安卓activity的切换动画 找了几个方法 这里记录下 使用Theme 最简单的就是设置没有动画的主题了 在activity上增加notAnimation的theme属性 android
  • 4.5.7 c++求灯塔数量

    4 5 7 灯塔数量 有一八层灯塔 每一层的灯数都是上一层的一倍 共有765盏灯 求最上层和最下层的灯数 include
  • C++:map&&set的简单使用

    目录 关联式容器 键值对 树形结构的关联式容器 set find与count multiset map multimap 关联式容器 在初期我们接触到的vector list deque queue等 这些容器都称为序列式容器 因为其底层为