哈希表的实现复杂了该容器上的双向遍历,似乎没有一种合适的方法能够做到高效快速。 因此,unorder版本的map和set只提供前向迭代器(非unorder版本提供双向迭代器)。

首先要include这个unordered_set头文件。
然后就是第六行我们定义了一个整型int的集合,叫myset。
后面几行,我们演示了insert/find/erase的用法。
有两点需要注意:
一是这个容器是个集合,所以重复插入相同的值是没有效果的。大家可以看到我们这里第7行和第9行插入了2次3,实际上这个集合里也只有1个3,第10行输出的结果是2。
二是find的返回值是一个迭代器(iterator),如果找到了会返回指向目标元素的迭代器,没找到会返回end()。

对于unordered_set,insert/find/erase的平均复杂度是O(1),但是最坏复杂度是O(N)的,这里N是指容器中元素数量。

有两种情况会出现O(N)复杂度。
1是你的哈希函数太烂了,导致很多不同元素的哈希值都相同,全是碰撞,这种情况复杂度会变成O(N)。但是这种情况一般不用担心,因为对于string以及int double之类的基本数据类型,都有默认的哈希函数,而且默认的哈希函数足够好,不会退化到O(N)。如果是你自定义的哈希函数,那你要小心一点,别写的太差了。
2是如果insert很多数据,会触发rehash。就是整个哈希表重建。这个过程有点类似向vector里不断添加元素,vector会resize。比如你新建一个vector时,它可能只申请了一块最多保存10个元素的内存,当你插入第11个元素的时候,它会自动重新申请一块更大空间,比如能存下20个元素。哈希表也是类似,不过rehash不会频繁发生,均摊复杂度还是O(1)的,也不用太担心。

unordered_set是一个集合,有的时候我们需要一个字典,就是保存一系列key/value对,并且可以按key来查询。比如我们要保存很多同学的成绩,每位同学有一个学号,也有一个分数,我们想按学号迅速查到成绩。这时候我们就可以用unordered_map。

unordered_map同样也提供了增删查函数:
unordered_map::insert
unordered_map::find
unordered_map::erase
这三个函数的平均时间复杂度也是O(1)的。我们可以看一个例子:

首先我们看第2行,要用unordered_map你要先include相应的头文件。
在7行我们定义了一个mymap,它的key是string类型,字符串;value是整形。
第8第9行展示的insert插入,因为我们这里要插入的是一个key/value pair(键值对),我们要用make_pair函数把一个字符串和一个整数打包成一个pair。
第10行是find查找,find返回的也是一个迭代器,iterator。这里我们懒得写很长的迭代器类型,直接用的auto。auto是c++11标准里的关键字,它会自动推断变量的类型。如果你的编译器不支持c++11,那你还是要老老实实写全:unordered_map<string, int>::iterator

迭代器指向的是一个pair,所以第11行我们可以用first和second去拿到对应的key和value,这里first是”c++”这个字符串,second是100这个整数。
第13第14行展示了一下erase删除。

值得一提的是,unordered_map重载了[]运算符,我们可以把key放在中括号里,像操作数组一样操作unordered_map:

上面这个程序的输出结果是101。大家可以看一下第8~第10行。我们把”c++”这个key放在中括号里就能直接操作”c++”对应的值。这种写法会让程序更直观。
--------------------- 
作者:夏普通 
来源:CSDN 
原文:https://blog.csdn.net/qq_34243930/article/details/81456582 
版权声明:本文为博主原创文章,转载请附上博文链接!

————————————————————————————————————————————————————————

unordered_set与与unordered_map相似,这次主要介绍unordered_set

unordered_set它的实现基于hashtable,它的结构图仍然可以用下图表示,这时的空白格不在是单个value,而是set中的key与value的数据包

有unordered_set就一定有unordered_multiset.跟set和multiset一样,一个key可以重复一个不可以

unordered_set是一种无序集合,既然跟底层实现基于hashtable那么它一定拥有快速的查找和删除,添加的优点.基于hashtable当然就失去了基于rb_tree的自动排序功能

unordered_set无序,所以在迭代器的使用上,set的效率会高于unordered_set

注:

一是这个容器是个集合,所以重复插入相同的值是没有效果的。大家可以看到我们这里第7行和第9行插入了2次3,实际上这个集合里也只有1个3,第10行输出的结果是2。
二是find的返回值是一个迭代器(iterator),如果找到了会返回指向目标元素的迭代器,没找到会返回end()。

对于unordered_set,insert/find/erase的平均复杂度是O(1),但是最坏复杂度是O(N)的,这里N是指容器中元素数量。

  1. template<class _Value,
  2. class _Hash = hash<_Value>,
  3. class _Pred = std::equal_to<_Value>,
  4. class _Alloc = std::allocator<_Value> >
  5. class unordered_set
  6. : public __unordered_set<_Value, _Hash, _Pred, _Alloc>
  7. {
  8. typedef __unordered_set<_Value, _Hash, _Pred, _Alloc> _Base;
  9. ...
  10. }  

参数1 _Value key和value的数据包

参数2 _Hash hashfunc获取hashcode的函数

参数3 _Pred 判断key是否相等

参数4 分配器

下面介绍一下unordered_set的基本使用,最后我会分享一下我的测试代码


一 定义

  1. //定义
  2. unordered_set<int> c1;
  3. //operator=
  4. unordered_set<int> c2;
  5. c2 = c1;

二 容量操作

  1. //判断是否为空
  2. c1.empty();
  3. //获取元素个数 size()
  4. c1.size();
  5. //获取最大存储量 max_size()
  6. c1.max_size();


三 迭代器操作

  1. //返回头迭代器 begin()
  2. unordered_set<int>::iterator ite_begin = c1.begin();
  3. //返回尾迭代器 end()
  4. unordered_set<int>::iterator ite_end = c1.end();
  5. //返回const头迭代器 cbegin()
  6. unordered_set<int>::const_iterator const_ite_begin = c1.cbegin();
  7. //返回const尾迭代器 cend()
  8. unordered_set<int>::const_iterator const_ite_end = c1.cend();
  9. //槽迭代器
  10. unordered_set<int>::local_iterator local_iter_begin = c1.begin(1);
  11. unordered_set<int>::local_iterator local_iter_end = c1.end(1);


四 基本操作

  1. //查找函数 find() 通过给定主键查找元素
  2. unordered_set<int>::iterator find_iter = c1.find(1);
  3. //value出现的次数 count() 返回匹配给定主键的元素的个数
  4. c1.count(1);
  5. //返回元素在哪个区域equal_range() 返回值匹配给定搜索值的元素组成的范围
  6. pair<unordered_set<int>::iterator, unordered_set<int>::iterator> pair_equal_range = c1.equal_range(1);
  7. //插入函数 emplace()
  8. c1.emplace(1);
  9. //插入函数 emplace_hint() 使用迭代器
  10. c1.emplace_hint(ite_begin, 1);
  11. //插入函数 insert()
  12. c1.insert(1);
  13. //删除 erase()
  14. c1.erase(1);//1.迭代器 value 区域
  15. //清空 clear()
  16. c1.clear();
  17. //交换 swap()
  18. c1.swap(c2);


五 篮子操作

  1. //篮子操作 篮子个数 bucket_count() 返回槽(Bucket)数
  2. c1.bucket_count();
  3. //篮子最大数量 max_bucket_count() 返回最大槽数
  4. c1.max_bucket_count();
  5. //篮子个数 bucket_size() 返回槽大小
  6. c1.bucket_size(3);
  7. //返回篮子 bucket() 返回元素所在槽的序号
  8. c1.bucket(1);
  9. // load_factor 返回载入因子,即一个元素槽(Bucket)的最大元素数
  10. c1.load_factor();
  11. // max_load_factor 返回或设置最大载入因子
  12. c1.max_load_factor();


六 内存操作

  1. // rehash 设置槽数
  2. c1.rehash(1);
  3. // reserve 请求改变容器容量
  4. c1.reserve(1000);

七 hash func

  1. //hash_function() 返回与hash_func相同功能的函数指针
  2. auto hash_func_test = c1.hash_function();
  3. //key_eq() 返回比较key值得函数指针
  4. auto key_eq_test = c1.key_eq();

unordered_set注意事项


for(auto it=v.begin();it!=v.end();it++)
//auto是c++11标准里的关键字,它会自动推断变量的类型。
//如果你的编译器不支持c++11,
//那你还是要老老实实写全:unordered_map<string, int>::iterator
//v.begin()返回的是一个指针类型所以想要具体的值还需要在前面加上*
set.find(key)
//如果key不存在,那么返回set.end()

unordered_map注意事项

class Solution {public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int,int> map;for(int i=0;i<nums.size();i++){auto it=map.find(target-nums[i]);if(it!=map.end()) return {it->second,i};map[nums[i]]=i;//或者 map.insert(make_pair(nums[i],i));}return {};}
};

上面这一段代码中注意以下几点

1.使用find(key)方法时,参数是key,同样的也是返回指针类型
2.key值保存在it->first中,value保存在it->second中
3.当我们使用insert方法插入键值对的时候需要在使用键值对函数make_pair()
4.我们还可以直接使用map[key]=value的方法

C++ STL 之 unordered_set 使用(包括unordersd_map)相关推荐

  1. 【C++】STL —— unordered_map/unordered_set的基本使用

    目录 unordered系列关联式容器 一.unordered_set 1. unordered_set的介绍 2. unordered_set的使用 3. unordered_set/unorder ...

  2. C++ STL(八) -------- unordered_set、unordered_map的介绍+使用+比较

    1.unordered系列关联式容器 在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时的效率可达到O(logN),即最差情况下需要比较红黑树的高度次,当树中的结点非常多时,查询 ...

  3. 【STL】unordered_set和unordered_map

    unordered_set和unordered_map unordered系列关联式容器 unordered_map unordered_map的使用方式 构造方式 unordered_map的函数接 ...

  4. C++STL面试详解

    1.什么是C++STL? C++ STL从广义来讲包括了三类:算法,容器和迭代器. 算法包括排序,复制等常用算法,以及不同容器特定的算法. 容器就是数据的存放形式,包括序列式容器和关联式容器,序列式容 ...

  5. C++ STL模板库用法查询及一些常见面试题(自用)

    C++STL模板库 文章目录 C++STL模板库 用法查询 Array 1.使用 2.创建 3.成员函数 Vector 1.使用 2. 创建 3.成员函数 deque 1.使用 2. 创建 3.成员函 ...

  6. 【STL模板库_(个人总结)】

    1.什么是STL? 2.解释一下什么是trivial destructor 3.使用智能指针管理内存资源,RAII是怎么回事? 4.迭代器:++it.it++哪个好,为什么 5.说一下C++左值引用和 ...

  7. [STL]面试题小结(一)

    修正时间:2021-7-31 修正二次:2021-09-14 文章目录 1 什么是STL 2 迭代器中i++,++i,哪一个好,为什么 3 左值引用和右值引用 4 STL 简单 hashtable 的 ...

  8. C++标准模板库(STL)的概念

    STL(Standard Template Library)标准模板库是 C++ 标准库中的一部分,标准模板库为 C++ 提供了完善的数据结构及算法. STL 标准模板库包括三部分:容器.算法和迭代器 ...

  9. C++STL总结笔记(一)—— 容器和容器适配器

    文章目录 前言 一.概念 1.1 顺序容器 1.2 容器适配器 1.3 关联容器 二.程序示例 1. vector和Set自定义数据类型的访问 2.vector容器嵌套 3.list容器排序 4.pa ...

最新文章

  1. 神经网络基础及逻辑回归实现
  2. 004-安装CentOS7后需要的操作
  3. Oracle日期相关
  4. 【渝粤题库】国家开放大学2021春2772家畜环境卫生与设施题目
  5. IOS--UIAlertView的使用方法详细
  6. js获取 jquery获取页面shu
  7. LeetCode 154 在有序旋转数组中找最小-2
  8. face 3000 C++ 代码理解
  9. python要学多久可以找到工作-自学Python的高效方法,学Python多久能找到工作?
  10. Flink – submitJob
  11. MATLAB点与点之间连线
  12. C语言之父丹尼斯·里奇
  13. java poi操作word转pdf
  14. iOS App 签名的原理 App 重签名(二)
  15. 小刘的每日知识点——10.22
  16. apm系统服务器,APM系统简单对比(zipkin,pinpoint和skywalking)
  17. average函数python_在Python3 numpy中mean和average的区别详解
  18. linux 杂项设备,浅谈 MISC杂项设备
  19. php实现播放直播_php和腾讯直播的实现代码
  20. DFC Session Management 白皮书

热门文章

  1. 仅靠一种普通的泡沫橡胶,这台机器人解决了“爬楼梯”的难题
  2. 全闪存阵列的“五十度黑”
  3. 利用poi进行数据的excel导出
  4. C++项目参考解答:累加求圆周率
  5. cacti 整合nagios,以及总是off处理办法!
  6. Altiris 7.1 远程
  7. linux双机(多机)自动互备份方案
  8. 【opencv系列05】OpenCV4.X鼠标回调函数
  9. 898. 子数组按位或操作
  10. 最坏情况为线性时间的选择算法