C++之unordered_set和unordered_map

C++之unordered_set和unordered_map

一、unordered系列关联式容器 

在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到log_2
N,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好
的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个
unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是
其底层结构不同

1.1 unordered_map 

1.2 unordered_map的文档介绍

1. unordered_map是存储<key, value>键值对的关联式容器,其允许通过keys快速的索引到与
其对应的value。
2. 在unordered_map中,键值通常用于惟一地标识元素,而映射值是一个对象,其内容与此
键关联。键和映射值的类型可能不同。
3. 在内部, unordered_map没有对<kye, value>按照任何特定的顺序排序, 为了能在常数范围内
找到key所对应的value,unordered_map将相同哈希值的键值对放在相同的桶中。
4. unordered_map容器通过key访问单个元素要比map快,但它通常在遍历元素子集的范围迭
代方面效率较低。
5. unordered_maps实现了直接访问操作符(operator[]),它允许使用key作为参数直接访问value。
6. 它的迭代器至少是前向迭代器。

1.3unordered_map的使用

unordered_map成员函数

unordered_map的使用

void test_unordered_map1() { unordered_map<string, string> dict; dict.insert(make_pair("insert", "插入")); dict.insert(make_pair("love", "爱")); dict["sort"] = "排序"; dict["miss"]; dict["miss"] = "想念、错过"; unordered_map<string, string>::iterator it = dict.begin(); while (it != dict.end()) { cout << it->first << ":" << it->second << endl; ++it; } cout << endl; } int main() { test_unordered_map1(); return 0; }

注意:
1、[ ]实际调用哈希桶的插入操作,用参数key与V()构造一个默认值往底层哈希桶
中插入,如果key不在哈希桶中,插入成功,返回V(),插入失败,说明key已经在哈希桶中,
将key对应的value返回。
2、unordered_map中key是不能重复的,因此count函数的返回值最大为1


1.4unordered_set的介绍

1、unordered_set是一种容器,它以任意顺序存储唯一的元素,并允许根据元素的值快速检索单个元素。
2、在unordered_set中,元素的值同时也是其键,用于唯一标识该元素。键是不可变的,因此,unordered_set中的元素一旦存入容器就不能被修改——不过可以插入和移除。
3、在内部,unordered_set中的元素并不按任何特定顺序排序,而是根据它们的哈希值被组织到各个桶中,以便通过元素的值直接快速访问单个元素(平均具有常数级的时间复杂度)。
4、unordered_set在通过键访问单个元素方面比有序集合容器更快,不过在对其部分元素进行范围迭代时,通常效率较低。
5、unordered_set的迭代器至少是前向迭代器。


1.5unordered_set的使用

unordered_set成员函数

unordered_set的使用

void test_unordered_set1() { unordered_set<int> us; us.insert(2); us.insert(3); us.insert(2); us.insert(1); us.insert(0); unordered_set<int>::iterator it = us.begin(); while (it != us.end()) { cout << *it << endl; ++it; } cout << endl; } int main() { test_unordered_set1(); return 0; }

注意:unordered_set只能去重,不能左到排序

1.6map、set、unordered_map、unordered_set性能测试

void test_performance() { const size_t N = 1000000; unordered_set<int> us; set<int> s; vector<int> v; v.reserve(N); srand((size_t)time(0)); for (size_t i = 0; i < N; ++i) { v.push_back(rand() + 1); } size_t begin1 = clock(); for (auto e : v) { s.insert(e); } size_t end1 = clock(); cout << "set insert:" << end1 - begin1 << endl; size_t begin2 = clock(); for (auto e : v) { us.insert(e); } size_t end2 = clock(); cout << "unordered_set insert:" << end2 - begin2 << endl; size_t begin3 = clock(); for (auto e : v) { s.find(e); } size_t end3 = clock(); cout << "set find:" << end3 - begin3 << endl; size_t begin4 = clock(); for (auto e : v) { us.find(e); } size_t end4 = clock(); cout << "unordered_set find:" << end4 - begin4 << endl << endl; cout <<"插入数据个数:"<< s.size() << endl; cout <<"插入数据个数:" << us.size() << endl << endl;; size_t begin5 = clock(); for (auto e : v) { s.erase(e); } size_t end5 = clock(); cout << "set erase:" << end5 - begin5 << endl; size_t begin6 = clock(); for (auto e : v) { us.erase(e); } size_t end6 = clock(); cout << "unordered_set erase:" << end6 - begin6 << endl << endl; }

运行结果:

总结:有大量重复数据的时候unordered_set、unordered_map更占优势,但是有序的数据set、map更占优势。

二、unordered_set和unordered_map的OJ题目

在长度2N的数组里找出重复N次的元素

思路:把其放到unordered_map里面去,然后统计次数,算出n的一半,然后找到那个出现次数为一半的元素

class Solution { public: int repeatedNTimes(vector<int>& nums) { unordered_map<int, int> countmap; for (auto element : nums) { countmap[element]++; } int count = nums.size() / 2; for (auto element : countmap) { if (element.second == count) { return element.first; } } //不可能的情况返回-1 return -1; } };

Read more

Python异步编程基石:深入理解asyncio核心原理与实战

Python异步编程基石:深入理解asyncio核心原理与实战

摘要 本文深入剖析Python异步编程核心库asyncio的工作原理,从事件循环、协程、Future到Task的完整技术栈。通过真实性能对比数据、企业级案例和5个架构流程图,全面解析async/await底层机制。涵盖异步编程最佳实践、性能优化技巧和故障排查方案,帮助开发者掌握高并发程序设计精髓,提升I/O密集型应用性能数倍。 1 异步编程:为什么它是Python高性能的关键 在我13年的Python开发经验中,异步编程是性能优化的分水岭。记得曾经处理一个需要调用10个外部API的任务,同步版本需要20多秒,而改用异步后仅需2秒——这种10倍性能提升让我彻底认识到异步编程的价值。 1.1 同步 vs 异步:直观对比 想象你在餐厅点餐的场景: * 同步:点完第一个菜后站着等厨师做完,再点第二个菜,效率极低 * 异步:点完所有菜后找座位等待,厨师并行制作,服务员送餐时通知你 这就是异步编程的核心优势:避免不必要的等待,充分利用等待时间执行其他任务。 import time import asyncio # 同步版本:顺序执行,总耗时=各任务耗时之和 def

By Ne0inhk
Python 小工具实战:图片水印批量添加工具

Python 小工具实战:图片水印批量添加工具

Python 小工具实战:图片水印批量添加工具 Python 小工具实战:图片水印批量添加工具,本文详细介绍了使用 Python开发 给图片加水印的工具,该工具基于 Pillow 和 tkinter 库构建,可解决单图处理耗时、专业软件操作复杂的问题。工具支持单图与批量处理,用户能自定义水印文字、字体大小、透明度及颜色,还可选择 9 个常用水印位置或设置行列重复分布。新增的全屏水印模式可通过调整旋转角度与间距,生成铺满图片的版权保护水印,且界面采用卡片式布局,搭配浅灰背景与蓝色按钮,简洁美观,底部状态栏实时显示操作进度。文中提供完整可运行代码,并给出参数校验、字体兼容、常见报错解决等实用内容,新手按步骤即可上手,或者直接运行使用。 前言     Python作为一门简洁、易读、功能强大的编程语言,其基础语法是入门学习的核心。掌握好基础语法,能为后续的编程实践打下坚实的基础。本文将全面讲解Python3的基础语法知识,适合编程初学者系统学习。Python以其简洁优雅的语法和强大的通用性,成为当今最受欢迎的编程语言。本专栏旨在系统性地带你从零基础入门到精通Python核心。无论你是

By Ne0inhk
Python 轻量化环境管理利器 UV 入门与 Windows 下安装实战

Python 轻量化环境管理利器 UV 入门与 Windows 下安装实战

文章目录 * 一、UV是什么?解决什么问题? * 1.1 传统Python环境管理的三大痛点 * 痛点1:多工具碎片化操作,效率低下 * 痛点2:依赖冲突与环境隔离难题 * 痛点3:工具学习成本高,协作壁垒明显 * 1.2 UV如何解决?核心优势解析 * 优势1:一体化设计,命令行极简主义 * 优势2:智能环境管理,冲突预警与自动隔离 * 优势3:轻量化与高性能,适配现代开发节奏 * 优势4:渐进式迁移,兼容现有生态 * 1.3 目标用户与典型场景 * 二、Windows下UV安装实战 * 2.1 前置步骤:安装Visual C++ 2015-2022运行时 * 2.1.1 为什么必须安装? * 2.1.2 安装步骤

By Ne0inhk
2026!在Windows的Python中安装GDAL包(小白能成!)

2026!在Windows的Python中安装GDAL包(小白能成!)

最近更新 2026.02.10日,GDAL发布预告:新版本将支持更多的指令! 新版本,以修复bug为主,提高稳定性! 有朋友催我赶紧更新教程,我上次更新是年前的时候了,恰好是GDAL上一个版本出来的时间。 前言 很多大气,地理,环境,生态,遥感,城市空间规划等专业的朋友,在各种终端尝试 pip install GDAL 指令时,都会遇到各种各样奇怪的报错,无论如何都安不上。说实话这条路走不通,不怪你。 因为GDAL不是标准的python库,不能直接用pip指令,进行管理操作。 实际证明,这样走不通的,请你放弃幻想。跟着这个教程一步一步的操作,你大概率是可以成功的。我会尽可能的详细,一步一步,足够缓慢,足够让每个第一次安装的朋友都能够明白。 感谢北京师范大学地理学院的朋友提供的帮助,我将把这个方法详细记录,希望可以帮助到更多朋友。 个人电脑配置说明 OS:Windows 11 Enterprise(MacOS和Linux的朋友,建议拉到文末,

By Ne0inhk