本节我们将进行unordered_multiset容器学习。对比前面我们学过的unordered_set容器,unordered_multiset容器的“特殊之处”在于允许出现重复值,也就是说unordered_multiset容器将“退化”成普通数组,由于其内的元素被哈希函数映射到桶数组里,所以还保持“无序”性,有别于普通数组。
unordered_multiset容器的创建和初始化与unordered_set容器无异,区别在于允许存在重复值:
#include<iostream> #include<unordered_set>//包含头文件,养成好习惯 #include<string> /*unordered_multiset*/ using namespace std; /*unordered_multiset的创建方式*/ void test() { unordered_multiset<int> ums1;//直接创建 unordered_multiset<int> ums2{5,4,3,2,1} ;//初始化列表 unordered_multiset<int> ums3(ums2) ;//拷贝构造 unordered_multiset<int> ums4; ums4=ums2;//'='运算符重载 unordered_multiset<int> ums5(ums2.begin(),ums2.end()) ;//迭代器范围构造 } int main(){ test(); return 0; }
代码完成编译,unordered_multiset容器成功创建和初始化。
接下来让我们看看unordered_multiset容器里都有哪些成员函数:
函数 | 参数 | 功能 |
---|---|---|
empty() | 无 | 检查容器是否为空 |
size() | 无 | 返回元素数量 |
max_size() | 无 | 返回可容纳的最大元素数 |
begin() | 无 | 返回指向起始的迭代器 |
end() | 无 | 返回指向末尾的迭代器 |
cbegin() | 无 | 返回指向起始的常量迭代器 |
cend() | 无 | 返回指向末尾的常量迭代器 |
insert() | const value_type& value | 插入元素(允许重复) |
initializer_list<value_type> ilist | 插入初始化列表中的元素 | |
emplace() | Args&&... args | 原位构造元素 |
| 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的元素数量 |
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_multiset容器的迭代器属于前向迭代器(迭代器能够进行++操作),切勿认为是随机迭代器(迭代器能够进行+5或-3操作)或双向迭代器(迭代器能够进行++或--操作)。
那我们就创建一个unordered_multiset容器然后简单地调用一些成员函数:
#include<iostream> #include<string> #include<unordered_set>//包含头文件,养成好习惯 /*初识unordered_multiset*/ using namespace std; /*调用unordered_multiset成员函数*/ void test() { unordered_multiset<int> ums; /*提前预存10个元素空间 原则上:预存空间>插入元素总和*/ ums.reserve(10); ums.insert(1) ; ums.emplace(25) ; ums.insert(10) ; ums.emplace(0); /*通过迭代器遍历unordered_multiset容器*/ /*迭代器为前向迭代器*/ cout << "通过迭代器遍历unordered_multiset容器: "; for(unordered_multiset<int>::iterator it = ums.begin();it!=ums.end();++it) cout << *it << " "; cout << '\n'; cout << "unordered_multiset容器里面总共有【" << ums.size() << "】个元素\n"; cout << "unordered_multiset容器的负载因子load_factor为【" << ums.load_factor() << "】"; ums.clear();//清除unordered_multiset容器 } int main(){ test(); return 0; }
编译结果为:
成功编译!
总结:unordered_multiset容器虽然“没啥用”退化成了“普通数组”,但是它能在批量数据中统计各个元素的个数,是查找重复元素个数的高效容器。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程