c++中 unordered_map 与 unordered_set 用法指南

unordered_map 与 unordered_set 区别与联系

unordered_mapunordered_set 都是 C++ 标准模板库(STL)中的容器,它们使用哈希表作为底层数据结构,提供了快速的查找、插入和删除操作。下面是它们之间的联系与区别:

联系

  1. 底层实现:两者都基于哈希表实现,利用了哈希函数来分布元素。
  2. 性能特点:它们都提供平均时间复杂度为 O(1) 的查找、插入和删除操作。
  3. 冲突解决:两者都使用某种形式的链表或红黑树来解决哈希冲突。
  4. 非线性容器:它们都是非线性容器,不保证元素的顺序。

区别

  1. 存储内容

    • unordered_map 存储键值对,即每个元素包含一个键(key)和一个值(value),键是唯一的。
    • unordered_set 只存储唯一的值,不包含键。
  2. 用途

    • unordered_map 适用于需要通过键来访问或存储数据的场景,类似于关联数组或字典。
    • unordered_set 适用于需要存储唯一元素集合的场景,类似于集合。
  3. 操作

    • unordered_map 支持通过键来访问、插入、删除和查找值。
    • unordered_set 支持插入、删除和查找元素。
  4. 内存使用

    • unordered_map 由于需要存储键和值,通常比 unordered_set 使用更多的内存。
  5. 迭代器

    • unordered_map 的迭代器可以解引用为一个 pair,其中包含键和值。
    • unordered_set 的迭代器只能解引用为一个值。
  6. 示例
    在这里插入图片描述

  7. 元素查找

    • unordered_mapfind 方法返回一个迭代器,指向键值对,可以访问键和值。
    • unordered_setfind 方法返回一个迭代器,指向集合中的元素。

使用场景

  • 当你需要一个键来快速访问数据时,使用 unordered_map
  • 当你只需要存储一组不包含重复元素的数据时,使用 unordered_set

总的来说,unordered_mapunordered_set 在实现上有很多相似之处,但它们服务于不同的数据存储需求。选择使用哪一个取决于你的具体应用场景和需求。

unordered_map

unordered_map 是 C++ 中的一个关联容器,它存储了键值对,并且提供了快速的数据访问能力。

  1. 基本使用
#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<int, std::string> umap;
    umap[1] = "one";
    umap[2] = "two";
    umap[3] = "three";

    // 打印所有键值对
    for (const auto& pair : umap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
}
  • 输出结果:

1: one
2: two
3: three
在这里插入图片描述

  1. 初始化列表
#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<int, std::string> umap = {
        {1, "one"},
        {2, "two"},
        {3, "three"}
    };

    // 打印所有键值对
    for (const auto& pair : umap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
}
  • 输出结果:

1: one
2: two
3: three
在这里插入图片描述

  1. 访问元素
#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<int, std::string> umap = {
        {1, "one"},
        {2, "two"}
    };

    // 访问元素
    std::cout << "Value for key 1: " << umap[1] << std::endl;
    // 访问不存在的键将自动插入该键,并为其分配一个默认值
    std::cout << "Value for key 3: " << umap[3] << std::endl; // 默认值,例如空字符串
}
  • 输出结果:

Value for key 1: one
Value for key 3:
在这里插入图片描述

  1. 检查键是否存在
#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<int, std::string> umap = {
        {1, "one"},
        {2, "two"}
    };

    int key = 1;
    if (umap.find(key) != umap.end()) {
        std::cout << "Key " << key << " exists." << std::endl;
    }
    else {
        std::cout << "Key " << key << " does not exist." << std::endl;
    }
}
  • 输出结果:

Key 1 exists.
在这里插入图片描述

  1. 删除元素
#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<int, std::string> umap = {
        {1, "one"},
        {2, "two"}
    };

    int keyToRemove = 1;
    auto it = umap.find(keyToRemove);
    if (it != umap.end()) {
        umap.erase(it);
    }

    // 打印删除元素后的映射
    for (const auto& pair : umap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
}
  • 输出结果:

2: two
在这里插入图片描述

  1. 使用 emplace 插入元素
#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<int, std::string> umap;

    // 使用 emplace 插入元素
    auto result = umap.emplace(1, "one");
    if (result.second) {
        std::cout << "Insert successful." << std::endl;
    }

    // 尝试再次插入相同的键
    result = umap.emplace(1, "uno");
    if (!result.second) {
        std::cout << "Insert failed, key already exists." << std::endl;
    }

    // 打印映射
    for (const auto& pair : umap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
}
  • 输出结果:

Insert successful.
Insert failed, key already exists.
1: one
在这里插入图片描述

  1. 遍历 unordered_map
#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<int, std::string> umap = {
        {1, "one"},
        {2, "two"},
        {3, "three"}
    };

    // 使用范围 for 循环遍历
    for (const auto& pair : umap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    // 使用迭代器遍历
    for (auto it = umap.begin(); it != umap.end(); ++it) {
        std::cout << it->first << ": " << it->second << std::endl;
    }
}
  • 输出结果:

1: one
2: two
3: three
1: one
2: two
3: three
在这里插入图片描述

  1. 使用 unordered_map 的 size 和 empty
#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<int, std::string> umap = {
        {1, "one"},
        {2, "two"}
    };

    std::cout << "Size of umap: " << umap.size() << std::endl;
    std::cout << "Is umap empty? " << (umap.empty() ? "Yes" : "No") << std::endl;
}
  • 输出结果:

Size of umap: 2
Is umap empty? No
在这里插入图片描述

unordered_set

  1. 基本使用
#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> uset;
    uset.insert(10);
    uset.insert(20);
    uset.insert(30);

    std::cout << "Size of uset: " << uset.size() << std::endl;
}
  • 输出结果:

Size of uset: 3
在这里插入图片描述

  1. 初始化列表
#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> uset = { 10, 20, 30, 40, 50 };

    for (int num : uset) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}
  • 输出结果:

50 10 20 30 40
在这里插入图片描述

  1. 检查元素是否存在
#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> uset = { 1, 2, 3 };

    int key = 2;
    if (uset.find(key) != uset.end()) {
        std::cout << "Element " << key << " exists in uset." << std::endl;
    }
    else {
        std::cout << "Element " << key << " does not exist in uset." << std::endl;
    }
}
  • 输出结果:

Element 2 exists in uset.
在这里插入图片描述

  1. 删除元素
#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> uset = { 1, 2, 3 };

    int keyToRemove = 2;
    if (uset.erase(keyToRemove)) {
        std::cout << "Element removed from uset." << std::endl;
    }
    else {
        std::cout << "Element not found in uset." << std::endl;
    }

    for (int num : uset) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}
  • 输出结果:

Element removed from uset.
1 3
在这里插入图片描述

  1. 使用 emplace 插入元素
#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> uset;

    // 使用 emplace 插入元素
    auto result = uset.emplace(10);
    if (result.second) {
        std::cout << "Insert successful." << std::endl;
    }

    // 尝试再次插入相同的元素
    result = uset.emplace(10);
    if (!result.second) {
        std::cout << "Insert failed, element already exists." << std::endl;
    }
}
  • 输出结果:

Insert successful.
Insert failed, element already exists.
在这里插入图片描述

  1. 遍历 unordered_set
#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> uset = { 5, 10, 15, 20, 25 };

    // 使用范围 for 循环遍历
    for (int num : uset) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 使用迭代器遍历
    for (auto it = uset.begin(); it != uset.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
}
  • 输出结果:

5 10 15 20 25
5 10 15 20 25
在这里插入图片描述

  1. 使用 unordered_set 的 size 和 empty
#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> uset = { 1, 2, 3 };

    std::cout << "Size of uset: " << uset.size() << std::endl;
    std::cout << "Is uset empty? " << (uset.empty() ? "Yes" : "No") << std::endl;
}
  • 输出结果:

Size of uset: 3
Is uset empty? No
在这里插入图片描述

  1. 清空 unordered_set
#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> uset = { 1, 2, 3, 4, 5 };

    uset.clear(); // 清空 uset

    std::cout << "Is uset empty after clear? " << (uset.empty() ? "Yes" : "No") << std::endl;
}
  • 输出结果:

Is uset empty after clear? Yes
在这里插入图片描述

  1. 自定义哈希函数
#include <iostream>
#include <unordered_set>

// 自定义哈希函数
struct custom_hash {
    std::size_t operator()(int x) const {
        return std::hash<int>()(x);
    }
};

int main() {
    std::unordered_set<int, custom_hash> uset = { 1, 2, 3 };

    for (int num : uset) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}
  • 输出结果:

1 2 3
在这里插入图片描述

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

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

相关文章

大数据分析统计

大数据分析统计 from datetime import datetimeimport pandas as pd import matplotlib.pyplot as pltpm25files [PM2.5_2021.csv, PM2.5_2022.csv, PM2.5_2023.csv] pm10files [PM10_2021.csv, PM10_2022.csv, PM10_2023.csv]def read_csv_file(files):# 每个文件都有表头…

ch5链路层和局域网

回顾TCP/IP参考模型&#xff0c;明确链路层和物理层在整个模型中的地位&#xff0c;简要提出链路层要解决的问题是单段链路的数据传输&#xff0c;物理层解决的是数字信号与电气信号之间的相互转换。 链路层概述 节点&#xff1a;主机和路由器(包括网桥和交换机) 链路&#xf…

移动端路由切换解决方案 —— 虚拟任务栈让你的 H5 像APP一样丝滑

目录 01: 前言 02: 通用组件&#xff1a;trigger-menu 和 trigger-menu-item 构建方案分析 03: 通用组件&#xff1a;构建 trigger-menu 和 trigger-menu-item 04: 前台业务下 H5 的应用场景 05: 通用组件&#xff1a;transition-router-view 构建方案分析 与 虚拟任务栈…

04Linux文件系统

课程目标 1、了解Linux操作系统的硬盘分区信息 2、了解Linux操作系统重各目录的作用 3、了解Linux的启动级别以及关机和重启命令 课程实验 在xshell中使用df -h &#xff0c;df -T&#xff0c;du -sh,fdisk -|,cd ,pwd 使用top &#xff0c;free&#xff0c;cat/proc/xxx…

ChaosBlade混沌测试实践

ChaosBlade: 一个简单易用且功能强大的混沌实验实施工具 官方仓库&#xff1a;https://github.com/chaosblade-io/chaosblade 1. 项目介绍 ChaosBlade 是阿里巴巴开源的一款遵循混沌工程原理和混沌实验模型的实验注入工具&#xff0c;帮助企业提升分布式系统的容错能力&…

面向对象技术

一、基本概念 二、设计原则 三、设计模式的概念与分类 四、创建型模式 五、结构型模式 六、行为型模式 七、Java程序设计

43-5 waf绕过 - 安全狗简介及安装

一、安全狗安装 安装安全狗需要开启 Apache 系统服务。如果 Apache 系统服务未开启,安装过程中可能会出现无法填入服务名称的问题,导致无法继续安装。为避免此问题,可以先在虚拟机中安装 PHPStudy。 安装PHPStudy 下载、安装phpstudy并启动(安装过程可以一路下一步,也…

使用Streamlit和MistralAI创建AI聊天机器人应用

大家好&#xff0c;创建交互式和用户友好型的应用程序通常需要复杂的框架和耗时的开发过程。Streamlit是一个Python库&#xff0c;它简化了以数据为重点的网络应用程序的创建过程&#xff0c;使开发人员和数据科学家能够快速将他们的想法转化为交互式仪表盘和原型。本文将介绍使…

【Java】数据加密

目录 数据加密介绍使用场景密码学历史古代密码学凯撒密码例子特点 维吉尼亚密码原理例子特点 现代密码学介绍 现代密码学的加密算法分类哈希算法优点缺点代码示例【封装写法】 对称加密算法对称加密算法的加密过程解密过程对称加密算法的优点&#xff1a;对称加密算法的缺点&am…

2024 cicsn Ezheap

文章目录 检查 libc2.35利用adddeleeditshow 思路exp结果 检查 libc2.35 利用 add 0x80个chunk&#xff0c;遍历选一个没有被用的&#xff0c;输入的size<0x501,然后malloc后会清零安装输入的size&#xff0c;然后输入内容&#xff0c;长度也是输入的size dele 指定索引…

你认识nginx吗,nginx是做什么的,nginx可以做什么 --1)nginx介绍

一.Nginx 介绍 Nginx&#xff08;发音同engine x&#xff09;是一个异步框架的 Web 服务器&#xff0c;也可以用作反向代理&#xff0c;负载平衡器 和 HTTP 缓存。该软件由 Igor Sysoev 创建&#xff0c;并于2004年首次公开发布。同名公司成立于2011年&#xff0c;以提供支持。…

JavaWeb_SpringBootWeb基础

先通过一个小练习简单了解以下SpringBootWeb。 小练习&#xff1a; 需求&#xff1a;使用SpringBoot开发一个Web应用&#xff0c;浏览器发起请求/hello后&#xff0c;给浏览器返回字符串"Hello World~"。 步骤&#xff1a; 1.创建SpringBoot项目&#xff0c;勾选We…

HTML 转义字符(escape characters)及其对应的符号(symbols)

以下是常见的 HTML 转义字符及其对应的符号&#xff0c;这些可以用于在 HTML 或 JSX 中避免解析错误和特殊字符的冲突&#xff1a; 空格 ( ): 或 引号: 单引号&#xff08;&#xff09;&#xff1a;&apos;、&lsquo;、、&rsquo;双引号&#xff08;"&#x…

互联网简史-分久必合,合久必分

六一儿童节&#xff0c;给孩子们讲讲互联网的历史。 任何当代技术都是古老技术的重组&#xff0c;这是真的。我从电话网络开始&#xff0c;两幅图完事。电波可以承载语音作为最开始&#xff0c;后面的事自然而然&#xff1a; 说实话&#xff0c;网络这种事&#xff0c;它的 …

面试必问:MySQL死锁是什么,如何解决?(史上最全)

MySQL死锁接触少&#xff0c;但面试又经常被问到怎么办&#xff1f; 最近有小伙伴在面试的时候&#xff0c;被问了MySQL死锁&#xff0c;如何解决&#xff1f; 虽然也回答出来了&#xff0c;但是不够全面体系化&#xff0c; 所以&#xff0c;小北给大家做一下系统化、体系化的…

Matlab里面的浮点数与FPGA定点数的相互转化应用(含Matlab代码,封装成函数可直接调用)

微信公众号获取更多FPGA相关源码&#xff1a; 1.前言 Matlab里面计算通常用的是浮点数&#xff0c;而FPGA在做数字信号处理时&#xff0c;为了节约资源&#xff0c;常常使用的是定点数。在实践中&#xff0c;我们经常需要将Matlab实现中的算法&#xff0c;用FPGA进行实现。 …

高效训练超越LoRA,北航发布MoRA

什么&#xff01;LoRA我都没有学懂&#xff0c;又出现了MoRA&#xff1f;&#xff1f;&#xff1f; LoRA作为当下最火热的大语言模型参数高效微调技术&#xff0c;正在以前所未有的速度迭代更新。从最初的LoRA到陆续推出的LoRA、DoRA、AsyLoRA等变体&#xff0c;LoRA家族可谓是…

深入探究 threejs 中的材质与纹理应用

深入探究 threejs 中的材质与纹理应用 一、引言 在三维图形开发领域&#xff0c;Three.js 是一个强大而受欢迎的库。其中&#xff0c;材质与纹理的应用对于创建逼真和吸引人的三维场景起着至关重要的作用。通过对材质和纹理的巧妙运用&#xff0c;可以极大地增强模型的视觉效…

C# WinForm —— 26 ImageList 介绍

1. 简介 图片集合&#xff0c;用于存储图像的资源&#xff0c;并在关联控件中显示出来 可以通过 索引、键名 访问每张图片 没有事件 2. 属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般以 imgList 开头ClolorDepth用于呈现图像的颜色数&#xff0c;默…

【开源】Wordpress自定义鼠标样式插件

插件简介 使用此插件可一键自定义Wordpress前端鼠标指针样式。利用该插件&#xff0c;站长可以快速实现替换多种鼠标指针样式于网站前端。 鼠标图案均来自于网络&#xff0c;插件仅作收集整理&#xff0c;插件完全开源无任何商业性质。 插件截图 使用教程 下载插件文件 下载…