本节我们将进入unordered_set容器的学习。对于unordered_set容器,我们至少能够知道它的两点规则,即:1. 不会像unordered_map容器一样进行自动排序,反而由于哈希表的缘故,元素根据键被哈希函数映射到桶数组里,显得“杂乱无序”;2. 存储的元素已不再是键值对,而是“值”且不允许存在重复值,我们可以认为它键值一体,还有就是其值不能通过迭代器或成员函数修改。
接下来我们将通过代码的方式学习如何创建一个unordered_set容器:
#include<iostream> #include<unordered_set>//包含头文件,养成好习惯 #include<string> /*unordered_set*/ using namespace std; /*unordered_set的创建方式*/ void test() { unordered_set<int> us1;//直接创建 unordered_set<int> us2{5,4,3,2,1} ;//初始化列表 unordered_set<int> us3(us2) ;//拷贝构造 unordered_set<int> us4; us4=us2;//'='运算符重载 unordered_set<int> us5(us2.begin(),us2.end()) ;//迭代器范围构造 } int main(){ test(); return 0; }
代码编译成功,unordered_set容器成功创建!
接下来让我们看看unordered_set容器里都有哪些成员函数:
函数 | 参数 | 功能 |
---|---|---|
empty() | 无 | 检查容器是否为空 |
size() | 无 | 返回元素数量 |
max_size() | 无 | 返回可容纳的最大元素数 |
begin() | 无 | 返回指向起始的迭代器 |
end() | 无 | 返回指向末尾的迭代器 |
cbegin() | 无 | 返回指向起始的常量迭代器 |
cend() | 无 | 返回指向末尾的常量迭代器 |
insert() | const value_type& value | 插入元素 |
initializer_list<value_type> ilist | 插入初始化列表中的元素 | |
emplace() | Args&&... args | 原位构造元素 |
erase() | const_iterator pos | 删除指定位置的元素 |
const key_type& key | 删除键为key的元素 | |
const_iterator first, const_iterator last | 删除迭代器范围内的元素 | |
clear() | 无 | 清空所有元素 |
find() | const key_type& key | 查找键为key的元素 |
count() | const key_type& key | 返回键为key的元素数量(0或1) |
equal_range() | const key_type& key | 返回键为key的元素范围 |
bucket_count() | 无 | 返回桶的数量 |
max_bucket_count() | 无 | 返回桶的最大数量 |
bucket_size() | size_type n | 返回第n个桶的大小 |
bucket() | const key_type& key | 返回键key所在的桶编号 |
load_factor() | 无 | 返回负载因子 |
max_load_factor() | 无 | 返回最大负载因子 |
float z | 设置最大负载因子 | |
rehash() | size_type count | 设置桶数为count并重新哈希 |
reserve() | size_type count | 预留空间至少容纳count个元素 |
hash_function() | 无 | 返回哈希函数对象 |
key_eq() | 无 | 返回键相等性判断函数对象 |
unordered_set容器的成员函数实际上与unordered_map容器大差不差,相比unordered_map容器而言,我们这里只需要记住unordered_set容器主要通过insert()和emplace()来添加元素,而且unordered_set容器没有at()来访问元素,其迭代器和所有无序关联式容器一样,都是前向迭代器。
那我们就创建一个unordered_set容器然后简单地调用一些成员函数:
#include<iostream> #include<string> #include<unordered_set>//包含头文件,养成好习惯 /*初识unordered_set*/ using namespace std; /*调用unordered_set成员函数*/ void test() { unordered_set<int> us; us.insert(1) ; us.emplace(25) ; us.insert(10) ; us.emplace(0); /*通过迭代器遍历unordered_set容器*/ cout << "通过迭代器遍历unordered_set容器: "; for(unordered_set<int>::iterator it = us.begin();it!=us.end();++it) cout << *it << " "; cout << '\n'; cout << "unordered_set容器里面总共有【" << us.size() << "】个元素\n"; us.clear();//清除unordered_set容器 } int main(){ test(); return 0; }
编译结果如下:
代码成功编译!
总结:不能因为unordered_set容器是非键值对插入就简单认为它是序列式容器,unordered_set容器本质是无序关联式容器,同时unordered_set容器能够实现元素去重,与unordered_map容器相比没有at()函数,也没有重载'[]'运算符,主要是通过emplace()或insert()插入元素,多个插入只能使用insert()。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程