C++STL—unordered_map和unordered_set介绍和使用

unordered_set和unordered_map的使用类似set和map。unordered_set是key模型。unordered_map是key/value模型,存储的数据类型是一个pair<key, value>。
map和set的底层是红黑树,unordered_map和unordered_set的底层是哈希表。他们的函数接口大部分相同,所以会使用map和set,也会使用unordered_map、unordered_set。

1、unordered_set

1.1、unordered_set简介

在这里插入图片描述
如果:第一个模板参数就是存储的数据类型Key,因为给了缺省值,所以我们使用的时候只要给出数据类型即可。包含于头文件<unordered_set>
第二个模板参数是哈希函数,unordered_set默认要求Key支持转换为整形,如果不支持或者想按自己的需求走可以自行实现支持将Key转成整形的仿函数传给第二个模板参数。
unordered_set默认要求Key支持比较相等,如果不支持或者想按自己的需求走可以自行实现支持将Key比较相等的仿函数传给第三个模板参数。
unordered_set底层是用哈希桶实现,增删查平均效率是O(1) ,迭代器遍历不再有序,为了跟set区分,所以取名unordered_set。


1.2、接口介绍及其使用

在这里插入图片描述
注意:unordered_set和unordered_map这里的迭代器是单向迭代器,没有反向迭代器。而且迭代器遍历是无序的(因为底层是哈希表),而map和set的迭代器遍历是有序的(中序遍历),因为map和set底层是红黑树。
find、count、equal_range使用类似前面map和set中的使用,有疑问移步前面写的map和set的介绍和使用。
相比于map和set多了Buckets中四个函数,因为底层是哈希桶(拉链法),函数取名都带了bucket(桶),但是用处并不大。


在这里插入图片描述
构造函数支持无参构造、迭代器区间构造、拷贝构造,后面两个需要到C++11才能看懂,因此unordered_set和unordered_map是C++11的产物,所以多了下面两个构造函数。
下面来看看基本使用方式:

#include <iostream>
#include <unordered_map>
#include <unordered_set>

using namespace std;

int main()
{
	unordered_set<int> us;
	us.insert(1);
	us.insert(3);
	us.insert(31);
	us.insert(15);
	us.insert(22);
	unordered_set<int>::iterator it = us.begin();
	while (it != us.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	us.erase(31);
	us.erase(1);
	for (auto& e : us)
		cout << e << " ";
	cout << endl;

	return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述
注意到:这里insert的返回值跟set一样返回的是pair<iterator, bool>。


2、unordered_map

2.1、unordered_map简介

在这里插入图片描述
后面三个模板参数跟前面set是一样的,但是unordered_map是key/value模型,所以数据类型有Key和T(Value)。包含于头文件<unordered_map>。


2.2、接口介绍及其使用

在这里插入图片描述
可以看到这里的接口跟unordered_set是一样的,同样是单向迭代器,只不过类似map,比unordered_set多了operator[]和at函数。通过实现operator[]可以插入和修改。
使用如下:

#include <iostream>
#include <unordered_map>
#include <unordered_set>

using namespace std;

int main()
{
	unordered_map<string, string> dict;
	dict.insert(make_pair("insert", "插入"));
	dict.insert(make_pair("sort", "排序"));
	dict["left"];			 // 插入
	dict["right"] = "右边";  // 插入+修改
	dict["left"] =  "左边";  // 修改

	unordered_map<string, string>::iterator it = dict.begin();
	while (it != dict.end())
	{
		cout << it->first << ":" << it->second << endl;
		++it;
	}
	cout << endl;
	dict.erase("sort");
	for (const auto& e : dict)
	{
		cout << e.first << ":" << e.second << endl;
	}
	return 0;
}

运行结果:

在这里插入图片描述
1、支持迭代器就支持范围for,因为范围for的底层就是替换成迭代器。
2、it->这里本质上是因为迭代器重载了operator->,返回的是数据类型的指针,也就是pair<K, V>*,正常应该写成it->->first,但是为了可读性优化成了一个->即可。
这些我们之前都有讲过,这里就不再赘述了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值