C++ 编程基础:深入理解 `pair`(键值对) 和 `unordered_map`(无序映射)
C++ 编程基础:深入理解 pair(键值对) 和 unordered_map(无序映射)
在 C++ 标准库中,
pair(键值对)和unordered_map(无序映射)是两种常用的数据结构,它们广泛应用于各种编程场景。pair用于存储两个相关联的值,而unordered_map通过哈希表来存储键值对,并提供高效的查找操作。本文将详细介绍这两种数据结构的定义、应用场景、核心原理和实现方法,并通过代码示例来说明它们的具体用法。
文章目录
- C++ 编程基础:深入理解 `pair`(键值对) 和 `unordered_map`(无序映射)
- 一、概述
- 二、`pair`(键值对)详解
- 2.1 `pair` 的定义
- 2.2 应用场景
- 2.3 示例代码
- 2.4 注意事项
- 三、`unordered_map`(无序映射)详解
- 3.1 `unordered_map` 的定义
- 3.2 应用场景
- 3.3 示例代码
- 3.4 注意事项
- 四、`pair` 和 `unordered_map` 的联系(★可直接看表格对比)
- 4.1 对比表格
- 4.2 示例:`unordered_map` 和 `pair` 的结合使用
- 五、结论
一、概述
pair(键值对) 是 C++ 中的一种简单结构,用于将两个相关联的值绑定在一起。常用于需要将两个数据成对存储的场景,如坐标对(x, y),或需要保存键值对时使用的 unordered_map 之类的数据结构。
unordered_map(无序映射) 则是一种基于哈希表的键值对容器,能够通过键快速查找对应的值。在 C++ 中,unordered_map 允许以 O(1) 的时间复杂度进行查找、插入和删除操作,适用于大规模数据的高效处理。
二、pair(键值对)详解
2.1 pair 的定义
pair 是 C++ 标准库中的模板类,用于将两个相关联的值存储在一起。它包含两个成员变量,first 和 second,分别表示这两个元素。通过 pair,我们可以将两个不同类型的值结合在一起,形成一个简单的键值对结构。
定义:
template <class T1, class T2>
struct pair {T1 first; // 第一个值T2 second; // 第二个值
};
2.2 应用场景
pair 广泛用于需要将两个数据关联存储的场景。它特别适用于以下情况:
- 关联数据:在某些情况下,我们需要将两个相关数据存储在一起,例如一个键和它对应的值。
pair提供了一种简单的方式来实现这一点。 - 返回多个值:在函数中,
pair也可以用作返回多个值的方式,因为 C++ 函数一次只能返回一个对象。使用pair可以让函数同时返回两个相关联的值。
尽管 pair 可以在某些数据结构中使用(例如 map 或 unordered_map),但这里强调的是它自身的结构特性,不应与这些数据结构混淆。
2.3 示例代码
以下代码展示了如何使用 pair 存储两个相关联的数据(一个整数和一个字符串),并输出它们的值。
#include <iostream>
#include <utility> // 引入pair的头文件
using namespace std;int main() {pair<int, string> p; // 定义一个pair,类型为int和stringp.first = 1; // 设置第一个值p.second = "apple"; // 设置第二个值cout << "第一个值:" << p.first << endl; // 输出第一个值cout << "第二个值:" << p.second << endl; // 输出第二个值return 0;
}
解释:在这个例子中,pair 被用来存储一个整数和一个字符串,通过 p.first 访问第一个元素,p.second 访问第二个元素。程序输出:
第一个值:1
第二个值:apple
2.4 注意事项
- 类型限制:
pair的两个元素可以是不同的类型,但每个元素的类型必须在声明时确定。即使pair可以存储任意类型的组合,但设计时应考虑到使用场景。 - 用途有限:
pair仅能存储两个值。如果需要存储多个相关值,建议使用tuple(元组),它允许存储任意数量的元素。
三、unordered_map(无序映射)详解
3.1 unordered_map 的定义
unordered_map 是 C++ 标准库中基于哈希表的容器,用于存储键值对。它的查找、插入和删除操作的平均时间复杂度为 O(1),因为它使用哈希函数来快速定位键值对。
定义:
template <class Key, class T>
class unordered_map {// 存储 Key 和 T 类型的键值对
};
3.2 应用场景
unordered_map(无序映射)非常适用于需要通过键快速查找值的场景,例如频率统计、数据分类等。它常用于实现哈希表相关的算法,如词频统计、缓存系统等。
3.3 示例代码
以下代码展示了如何使用 unordered_map 存储多个键值对,并查找某个键是否存在。
#include <iostream>
#include <unordered_map> // 引入unordered_map的头文件
using namespace std;int main() {// 定义一个unordered_map,键为int,值为stringunordered_map<int, string> umap;// 插入键值对umap[1] = "apple";umap[2] = "banana";umap[3] = "cherry";// 查找键为2的值if (umap.find(2) != umap.end()) {cout << "键为2的值是:" << umap.at(2) << endl; // 输出:banana}// 遍历unordered_mapfor (const auto& entry : umap) {cout << "键:" << entry.first << ", 值:" << entry.second << endl;}return 0;
}
解释:在这个例子中,使用 unordered_map 存储了三个键值对。程序首先通过 find 方法查找键 2 对应的值,若找到则输出其值。随后,程序遍历 unordered_map 并输出所有键值对。输出如下:
键为2的值是:banana
键:1, 值:apple
键:2, 值:banana
键:3, 值:cherry
3.4 注意事项
- 哈希冲突:由于
unordered_map基于哈希表,可能会发生哈希冲突(即不同的键计算出的哈希值相同)。在这种情况下,unordered_map通过链表等方式处理冲突。 - 键类型要求:键必须能够通过哈希函数计算出哈希值,因此通常要求键类型满足以下条件:
- 支持相等比较:键类型必须实现
==操作符,以便在查找、插入和删除时比较键的相等性。 - 可哈希:键类型需要支持哈希函数(如
std::hash),这通常意味着自定义类型需要提供哈希函数的重载,以便能够在unordered_map中正确工作。
- 支持相等比较:键类型必须实现
四、pair 和 unordered_map 的联系(★可直接看表格对比)
在 C++ 中,unordered_map 内部是通过 pair 来存储键值对的。每个 unordered_map 元素实际上是一个 pair<const Key, T>,其中 Key 是键,T 是值。
4.1 对比表格
| 特性 | pair | unordered_map |
|---|---|---|
| 存储结构 | 仅存储两个相关值 | 存储键值对,基于哈希表 |
| 查找效率 | 不支持直接查找 | 平均 O(1) 时间复杂度查找 |
| 用途 | 简单关联数据存储 | 高效键值对存储与查找 |
| 元素个数 | 仅可存储两个元素 | 可存储多个键值对 |
| 应用场景 | 坐标、返回多个值的函数 | 频率统计、数据分类等 |
4.2 示例:unordered_map 和 pair 的结合使用
以下代码展示了如何将 unordered_map 中的键值对转存到一个 vector<pair> 中,并对其进行排序。
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;// 比较函数,用于按值的大小排序
bool cmp(const pair<int, string>& a, const pair<int, string>& b) {return a.second < b.second; // 按值从小到大排序
}int main() {unordered_map<int, string> umap;umap[1] = "banana";umap[2] = "apple";umap[3] = "cherry";// 将unordered_map转换为vector<pair>vector<pair<int, string>> vec(umap.begin(), umap.end());// 按照值进行排序sort(vec.begin(), vec.end(), cmp);// 输出排序后的键值对for (const auto& pair : vec) {cout << "键:" << pair.first << ", 值:" << pair.second << endl;}return 0;
}
解释:在这个例子中,首先将 unordered_map 中的键值对存入 vector<pair>,然后使用自定义的比较函数按值对键值对进行排序。程序输出按值排序后的键值对:
键:2, 值:apple
键:1, 值:banana
键:3, 值:cherry
五、结论
pair 和 unordered_map 是 C++ 标准库中用于存储和操作键值对的两种重要数据结构。pair 提供了简单的成对元素存储机制,而 unordered_map 则提供了高效的键值映射。两者经常结合使用,unordered_map 通过 pair 存储键值对,使得键值操作更加灵活和高效。
对于初学者,理解这两种数据结构的概念及其应用场景,可以帮助在实际编程中更好地管理和处理数据。通过本文的示例代码,你可以直观地理解它们的实现和作用,并在需要时灵活运用。
✨ 我是专业牛,一个渴望成为大牛🏆的985硕士🎓,热衷于分享知识📚,帮助他人解决问题💡,为大家提供科研、竞赛等方面的建议和指导🎯。无论是科研项目🛠️、竞赛🏅,还是图像🖼️、通信📡、计算机💻领域的论文辅导📑,我都以诚信为本🛡️,质量为先!🤝
如果你觉得这篇文章对你有所帮助,别忘了点赞👍、收藏📌和关注🔔!你的支持是我继续分享知识的动力🚀!✨ 如果你有任何问题或需要帮助,随时留言📬或私信📲,我都会乐意解答!😊
相关文章:
C++ 编程基础:深入理解 `pair`(键值对) 和 `unordered_map`(无序映射)
C 编程基础:深入理解 pair(键值对) 和 unordered_map(无序映射) 在 C 标准库中,pair(键值对)和 unordered_map(无序映射)是两种常用的数据结构,它…...
高德动态地图
1.搭建页面结构 <div class"dataAllBorder02" style"position: relative; overflow: hidden;"><div class"map_title_box" style"height: 6%"><div class"map_title_innerbox"><div class"map_t…...
springboot集成camunda学习与使用
springboot集成camunda学习与使用.md 0、前言一、Spring Boot 集成camunda流程引擎1.新建全新的springboot工程2.添加pom.xml依赖3.启动Spring Boot工程4.切换成mysql数据库5.设计并部署一个BPMN流程6.camunda流程引擎测试6.1 通过camunda web控制台测试6.2 通过camunda rest接…...
微服务架构学习笔记
#1024程序员节|征文# 微服务架构作为现代软件开发中的热门技术架构,因其灵活性和可扩展性,逐渐成为许多企业系统设计的首选。以下是关于微服务的一些学习笔记,涵盖微服务的核心概念、优缺点、设计原则以及常用工具等方面。 1. 微服务是什么&…...
代码优化之简化if臃肿的判断条件
简化if判断条件 方法1: #include <iostream> #include <vector> #include <functional>// 封装参数的结构体 struct ConditionParams {int facenum;double zoomRatio;int iso;double facelv;int face_w;double qualityScore;int xx;int yy; };//…...
【OpenAI】第六节(语音生成与语音识别技术)从 ChatGPT 到 Whisper 的全方位指南
前言 在人工智能的浪潮中,语音识别技术正逐渐成为我们日常生活中不可或缺的一部分。随着 OpenAI 的 Whisper 模型的推出,语音转文本的过程变得前所未有的简单和高效。无论是从 YouTube 视频中提取信息,还是将播客内容转化为文本,…...
Docker 下备份恢复oracle
1.docker导出容器镜像 ##docker save -o 导出后的镜像名称.tar 容器名称|镜像id docker save -o oracle_11g.tar 3fa112fd3642 2.下载镜像上传镜像略 3.加载镜像 ##docker load -i <archive_file> docker load -i oracle11g11201.tar 4.添加版本号…...
oneplus3t-android_framework
0.确认oneplus6 root正常 oneplus6 root材料 oneplus6手机恢复出厂设置 , 或者 线刷 enchilada_22_K.52_210716_repack--HOS-10.0.11.zip : https://gitee.com/OnePlus6-brick-enchilada_22_K_52_210716_repack-HOS-10_0_11-zip OnePlus6Hydrogen_22…...
偷懒总结篇|贪心算法|动态规划|单调栈|图论
由于这周来不及了,先过一遍后面的思路,具体实现等下周再开始详细写。 贪心算法 这个图非常好 122.买卖股票的最佳时机 II(妙,拆分利润) 把利润分解为每天为单位的维度,需要收集每天的正利润就可以,收集正利润的区间…...
C语言初阶七:C语言操作符详解(1)
#1024程序员节|征文# 这篇文章是对之前文章中操作符的补充,可以看之前的文章:C语言初阶:六.算数操作_如何用编程表示除法-CSDN博客 C语言操作符是用于执行各种运算和操作的符号。包括算术操作符(如、-、*、/、%)&#…...
GO excelize 读取excel进行时间类型转换(自动转换)
GO excelize 读取excel进行时间类型转换(自动转换) 需求分析 需求:如何自动识别excel中的时间类型数据并转化成对应的 "Y-m-d H:i:s"类型数据。 分析:excelize在读取excel时,GetRows() 返回的都是字符串类…...
【算法与数据结构】二分查找思想
#1024程序员节|征文# 正文: 二分查找(binary search)是一种基于分治策略的高效搜索算法。它利用数据的有序性,每轮缩小一半搜索范围,直至找到目标元素或搜索区间为空为止,其实有时候数据没有序…...
PHP PDO:安全、灵活的数据持久层解决方案
PHP PDO:安全、灵活的数据持久层解决方案 PHP PDO(PHP Data Objects)是一个轻量级的、具有兼容接口的数据持久层抽象层。它提供了一个统一的API来访问多种数据库系统,如MySQL、PostgreSQL、SQLite、Oracle等。PDO扩展在PHP 5.1.0…...
九、Linux实战案例:项目部署全流程深度解析
Linux实战案例:项目部署全流程深度解析 在当今信息技术领域,Linux服务器凭借其卓越的稳定性、安全性以及强大的性能表现,被广泛应用于各类项目部署场景之中。本文将全面深入地介绍如何将一个项目成功部署至Linux服务器的完整流程,…...
GIS常见前端开发框架
#1024程序员节|征文# 伴随GIS的发展,陆续出现了众多开源地图框架,这些地图框架与众多行业应用融合,极大地拓展了GIS的生命力,这里介绍几个常见的GIS前端开发框架,排名不分先后。 1.Leaflet https://leafl…...
Java | Leetcode Java题解之第506题相对名次
题目: 题解: class Solution {public String[] findRelativeRanks(int[] score) {int n score.length;String[] desc {"Gold Medal", "Silver Medal", "Bronze Medal"};int[][] arr new int[n][2];for (int i 0; i &…...
数据结构 - 堆
今天我们将学习新的数据结构-堆。 01定义 堆是一种特殊的二叉树,并且满足以下两个特性: (1)堆是一棵完全二叉树; (2)堆中任意一个节点元素值都小于等于(或大于等于)左…...
html----图片按钮,商品展示
源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>图标</title><style>.box{width:…...
YOLOv11改进策略【卷积层】| ECCV-2024 小波卷积WTConv 增大感受野,降低参数量计算量,独家创新助力涨点
一、本文介绍 本文记录的是利用小波卷积WTConv模块优化YOLOv11的目标检测网络模型。WTConv的目的是在不出现过参数化的情况下有效地增加卷积的感受野,从而解决了CNN在感受野扩展中的参数膨胀问题。本文将其加入到深度可分离卷积中,有效降低模型参数量和计算量,并二次创新C3…...
redis高级篇之redis源码分析List类型quicklist底层演变 答疑159节
(1)ziplist压缩配置:list-compress-depth 0 表示一个quicklist两端不被压缩的节点个数。这里的节点是指quicklist双向链表的节点,而不是指ziplist里面的数据项个数参数list-compress-depth的取值含义如下: 0:是个特殊值,表示都不压缩。这是Redis的默认值…...
别再只会用灰度图做均衡化了!OpenCV彩色图像直方图均衡化实战(附完整代码)
突破灰度局限:OpenCV彩色图像直方图均衡化的专业实践指南 当你在处理一张背光拍摄的人像照片时,直接应用灰度图的均衡化方法会导致什么结果?色彩失真、肤色异常、细节丢失——这正是许多计算机视觉工程师在项目初期常犯的错误。本文将带你深入…...
5分钟搞定Qwen2-7B本地部署:从GGUF下载到API调用的保姆级教程
5分钟极速部署Qwen2-7B:从模型下载到API调用的实战手册 在人工智能技术快速迭代的今天,能够在本地高效运行大语言模型已成为开发者的一项核心竞争力。Qwen2-7B作为当前最受关注的中等规模开源模型之一,以其出色的中文理解能力和适中的硬件需求…...
MCP协议实战踩坑:当Claude Desktop遇上n8n 1.93.0的混合通信
MCP协议深度解析:从混合通信模型看AI Agent生态兼容性挑战 当Claude Desktop与n8n 1.93.0的MCP协议实现相遇时,表面上的连接故障背后隐藏着AI Agent通信架构的深层设计哲学差异。本文将带您穿透现象看本质,揭示不同MCP实现方案背后的技术权衡…...
OpenClaw浏览器自动化:Qwen3.5-9B驱动复杂网页操作实录
OpenClaw浏览器自动化:Qwen3.5-9B驱动复杂网页操作实录 1. 为什么选择OpenClaw做浏览器自动化? 去年冬天,我为了给家里老人买一台性价比高的空气净化器,连续三天晚上手动比价到凌晨两点。在不同电商平台反复切换标签页、记录价格…...
HarmonyOS开发入门:DevEco Studio工程目录结构详解与实战配置
HarmonyOS开发实战:深度解析DevEco Studio工程架构与高效配置策略 当你第一次在DevEco Studio中创建HarmonyOS项目时,是否曾被复杂的目录结构弄得一头雾水?作为华为全场景智能生态的核心开发工具,DevEco Studio采用了一套精心设计…...
WebRTC信令交换实战:从Socket.io到RTCPeerConnection的完整流程解析
1. WebRTC信令交换的核心逻辑 第一次接触WebRTC时,我被它"点对点直接通信"的特性吸引,但很快发现真正的难点在于如何让两个设备找到彼此——这就是信令交换要解决的问题。信令交换就像两个陌生人交换电话号码的过程,只不过这里交换…...
RoboMaster装甲板灯条匹配算法实战:从图像预处理到目标框定(附完整C++/OpenCV源码)
1. 项目背景与核心挑战 RoboMaster机甲大师赛中的装甲板识别是自动瞄准系统的关键技术难点。赛场上高速移动的机器人装甲板通常配备LED灯条作为视觉标识,这种设计让计算机视觉算法能够在复杂环境下快速定位目标。但实际开发时会遇到几个头疼的问题:强光干…...
鸽姆智库(GG3M Think Tank)核心优势 |Core Strengths of GG3M Think Tank
鸽姆智库(GG3M Think Tank)核心优势鸽姆智库(GG3M Think Tank)的核心优势体现在理论原创性、技术架构创新、东方智慧深度融入与全场景工程落地能力四大维度,构成全球首个以东方哲学为根基的“文明级操作系统”…...
百川2-13B-4bits模型商用指南:OpenClaw自动化服务合规部署要点
百川2-13B-4bits模型商用指南:OpenClaw自动化服务合规部署要点 1. 商用授权与合规基础 百川2-13B-4bits模型作为国内少数明确开放商用申请的大语言模型,其授权体系与常见的开源协议有本质区别。我在实际部署过程中发现,很多开发者容易忽略一…...
FireRed-OCR StudioGPU适配方案:多卡并行解析长文档的配置详解
FireRed-OCR StudioGPU适配方案:多卡并行解析长文档的配置详解 1. 工业级文档解析工具概述 FireRed-OCR Studio是一款基于Qwen3-VL模型开发的下一代文档解析工具,专为处理复杂文档场景设计。它不仅能够精准识别文字内容,更能完整还原文档中…...
