C++ -- STL【unordered_set和unordered_map的使用】

目录

1、unordered_set的介绍

2、unordered_set的功能

[2.1 初始化](#2.1 初始化)

[2.2 迭代器](#2.2 迭代器)

[2.3 常见成员函数](#2.3 常见成员函数)

3、unordered_multiset

4、unordered_map的介绍

[5、unordered_map 的功能](#5、unordered_map 的功能)

[5.1 初始化](#5.1 初始化)

[5.2 迭代器](#5.2 迭代器)

[5.3 常见成员函数](#5.3 常见成员函数)

6、unordered_multimap


1、unordered_set的介绍

unordered_set 是一种关联式容器,它具有以下几个特点:

具体可参考官方文档 ------unordered_set

2、unordered_set的功能

2.1 初始化

unordered_set 初始化会调用构造函数,其构造函数分别重载了以下几种方式:

cpp 复制代码
void Test1()
{
	//1.默认无参构造
	unordered_set<int> s1;
	//2.迭代器区间初始化
	string str("tata");
	unordered_set<char> s2(str.begin(), str.end());
	//3.拷贝构造
	unordered_set<int> s3(s1);
}

2.2 迭代器

成员函数 功能
begin 获取容器中第一个元素的迭代器
end 获取容器中最后一个元素下一个位置的正向迭代器

一般而言 unordered_set 并不支持反向迭代器,其次这些函数与其他容器的迭代器成员函数无论是功能还是用法都是一模一样的。

cpp 复制代码
void Test2()
{
	vector<int> arr = { 1,2,3,4,5,6,7 };
	//迭代器区间初始化
	unordered_set<int> s1(arr.begin(), arr.end());
	//正向迭代器
	unordered_set<int>::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

2.3 常见成员函数

下是 unordered_set 常见的成员函数:

成员函数 功能
insert 插入指定元素
erase 删除指定元素
find 查找指定元素
size 获取容器中元素的个数
empty 判断容器是否为空
clear 清空容器
swap 交换两个容器中的数据
count 获取容器中指定元素值的元素个数
cpp 复制代码
void Test3()
{
	unordered_set<int> s1;
	//插入元素并去重
	s1.insert(1);
	s1.insert(2);
	s1.insert(2);
	s1.insert(3);
	s1.insert(3);
	for (auto e : s1)
	{
		cout << e << " ";
	}
	cout << endl; 
	unordered_set<int>::iterator it = s1.find(1);
	//如果找不到返回end()
	if (it != s1.end())
	{
		s1.erase(1);
	}
	for (auto e : s1)
	{
		cout << e << " ";
	}
	cout << endl;
	//容器中值为2的元素个数
	cout <<"容器中值为2的元素个数"<< s1.count(2) << endl;
}
cpp 复制代码
void Test4()
{
	unordered_set<int> s1;
	s1.insert(1);
	s1.insert(2);
	s1.insert(3);
	//容器大小
	cout << s1.size() << endl;
	//清空容器
	s1.clear();
	//容器判空
	cout << s1.empty() << endl;
	vector<int> arr = { 1,2,3,4,5,6,7 };
	//迭代器区间初始化
	unordered_set<int> tmp(arr.begin(), arr.end());
	//交换两个容器的数据
	s1.swap(tmp);
	for (auto e : s1)
	{
		cout << e << " ";
	}
	cout << endl;
}

值得注意的是:unordered_set 的插入与删除操作可能存在迭代器失效的问题。

3、unordered_multiset

unordered_multiset 的使用方式与 unordered_set 基本一致,唯一的区别就在于 unordered_multiset 允许键值冗余,即可存储重复元素。

cpp 复制代码
void Test5()
{
	unordered_multiset<int> s1;
	//支持键值冗余
	s1.insert(1);
	s1.insert(1);
	s1.insert(2);
	s1.insert(2);
	s1.insert(3);
	s1.insert(4);
	unordered_multiset<int>::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << " ";
		++it;
	}
}

值得注意的是:unordered_multiset 的 find 返回返回底层哈希表中第一个找到的键值为 val 的元素的迭代器。

4、unordered_map的介绍

unordered_map 是 C++ 中的关联式容器,具有以下特性:

具体可参考官方文档 ------unordered_map

5、unordered_map 的功能

首先 unordered_map 同样与 STL 其他大多数容器一样,为了支持所有类型,所以是一个类模版。

5.1 初始化

unordered_map 初始化会调用构造函数,其构造函数分别重载了以下几种方式:

cpp 复制代码
void Test6()
{
	//1.默认无参构造
	unordered_map<int, int> m1;
	//2.迭代器区间初始化
	unordered_map<int, int> m2(m1.begin(), m1.end());
	//3.拷贝构造
	unordered_map<int, int> m3(m1);
}

5.2 迭代器

成员函数 功能
begin 获取容器中第一个元素的迭代器
end 获取容器中最后一个元素下一个位置的正向迭代器

一般而言 unordered_map 并不支持反向迭代器,其次这些函数也与其他容器的迭代器成员函数无论是功能还是用法都是一模一样的。

cpp 复制代码
void Test7()
{
	unordered_map<int, string> m;
	m.insert(pair<int, string>(1, "one"));
	m.insert(pair<int, string>(2, "two"));
	m.insert(pair<int, string>(3, "three"));
	//正向迭代器
	unordered_map<int, string>::iterator it = m.begin();
	while (it != m.end())
	{
		cout << "<" << it->first << "," << it->second << ">" << " ";
		++it;
	}
	cout << endl;
}

5.3 常见成员函数

unordered_map 与unordered_set 的成员函数类似,只不过多了一个 [ ] 运算符重载。

成员函数 功能
insert 插入指定元素
erase 删除指定元素
find 查找指定元素
size 获取容器中元素的个数
empty 判断容器是否为空
clear 清空容器
swap 交换两个容器中的数据
count 获取容器中指定元素值的元素个数
[ ] 运算符重载 返回 key 所对应的 val
cpp 复制代码
void Test8()
{
	unordered_map<int,string> m1;
	//插入元素并去重
	m1.insert(make_pair(1,"one"));
	m1.insert(make_pair(1,"one"));
	m1.insert(make_pair(2, "two"));
	m1.insert(make_pair(2, "two"));
	m1.insert(make_pair(3, "three"));
	m1.insert(make_pair(3, "three"));
	unordered_map<int, string>::iterator it = m1.begin();
	while (it != m1.end())
	{
		cout << "<" << it->first << "," << it->second << ">" << " ";
		++it;
	}
	cout << endl;
	it = m1.find(1);
	//如果找不到返回end()
	if (it != m1.end())
	{
		m1.erase(1);
	}
	it = m1.begin();
	while (it != m1.end())
	{
		cout << "<" << it->first << "," << it->second << ">" << " ";
		++it;
	}
	cout << endl;
	//容器中值为2的元素个数
	cout << "容器中值为2的元素个数" << m1.count(2) << endl;
}
cpp 复制代码
void Test9()
{
	unordered_map<int,string> m1;
	m1.insert(pair<int, string>(1, "one"));
	m1.insert(pair<int, string>(2, "two"));
	m1.insert(pair<int, string>(3, "three"));
	//容器大小
	cout << m1.size() << endl;
	//清空容器
	m1.clear();
	//容器判空
	cout << m1.empty() << endl;
	unordered_map<int, string> tmp;
	tmp.insert(pair<int, string>(4, "four"));
	tmp.insert(pair<int, string>(5, "five"));
	tmp.insert(pair<int, string>(6, "six"));
	//交换两个容器的数据
	m1.swap(tmp);
	unordered_map<int, string>::iterator it = m1.begin();
	while (it != m1.end())
	{
		cout << "<" << it->first << "," << it->second << ">" << " ";
		++it;
	}
	cout << endl;
}

值得注意的是:unordered_map 的插入与删除操作可能存在迭代器失效的问题。

6、unordered_multimap

unordered_multimap 的使用方式与 unordered_map 基本一致,唯一的区别就在于unordered_multimap 允许键值冗余,即可存储重复元素。

cpp 复制代码
void Test9()
{
	//允许键值冗余
	unordered_multimap<int, string> m;
	m.insert(make_pair(1, "one"));
	m.insert(make_pair(1, "1"));
	m.insert(make_pair(2, "two"));
	m.insert(make_pair(2, "2"));
	m.insert(make_pair(3, "three"));
	for (auto e : m)
	{
		cout << "<" << e.first << "," << e.second << ">" << " ";
	}
	cout << endl; 
}

值得注意的是:unordered_multimap 的 find 返回底层哈希表中第一个找到的键值为 key 的键值对的迭代器,而 unordered_map 返回的是 key 元素的迭代器。并且由于 unordered_multimap 支持键值冗余,所以其成员函数没有 [ ] 运算符重载,因为一旦键值容易,根本不知道该返回哪个键值的 value。

思考:为什么 unordered_map/unordered_set 存在迭代器失效的问题,而 map/set 就没有呢?

其实这种说法并不准确,因为 unordered_map/unordered_set 通常是基于哈希表实现,哈希表插入或删除时可能需要移动桶中的元素(扩容)或重新链接元素(扩容或删除桶中元素),这个操作会导致指向这些桶的迭代器失效。而 map/set 通常基于红黑树实现,红黑树的删除操作只涉及树节点的重新链接和旋转,不影响其他节点的内存位置。所以插入/删除操作不会导致对其他节点迭代器失效(但是指向该删除节点的迭代器是失效的)。

相关推荐
star _chen3 小时前
C++ std::move()详解:从小白到高手
开发语言·c++
福尔摩斯张3 小时前
C++核心特性精讲:从C语言痛点出发,掌握现代C++编程精髓(超详细)
java·linux·c语言·数据结构·c++·驱动开发·算法
charlie1145141913 小时前
如何快速在 VS2026 上使用 C++ 模块 — 完整上手指南
开发语言·c++·笔记·学习·现代c++
报错小能手4 小时前
STL_unordered_map
开发语言·c++·哈希算法
历程里程碑4 小时前
C++ 9 stack_queue:数据结构的核心奥秘
java·开发语言·数据结构·c++·windows·笔记·算法
仰泳的熊猫4 小时前
1108 Finding Average
数据结构·c++·算法·pat考试
AA陈超5 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P07-18.生成火球术
c++·游戏·ue5·游戏引擎·虚幻
wxin_VXbishe5 小时前
springboot居家养老管理系统-计算机毕业设计源码55953
java·c++·spring boot·python·spring·django·php
ULTRA??6 小时前
归并排序算法实现,kotlin,c++,python
c++·python·kotlin