unordered_map和unordered的介绍和使用

目录

unordered系列关联式容器

unordered_map

unordered_map的接口说明

unordered_map的定义方式

unordered_map接口的使用

unordered_map的容量

unordered_map的迭代器

unordered_map的元素访问

unordered_map的查询

unordered_map的修改操作

unordered_multimap

unordered_set

unordered_set的定义方式

unordered_set的接口使用

unordered_multiset


unordered系列关联式容器

在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到logN,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个 unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同

unordered_map

  1. unordered_map是存储键值对的关联式容器,其允许通过keys快速的索引到与 其对应的value。

  2. 在unordered_map中,键值通常用于惟一地标识元素,而映射值是一个对象,其内容与此 键关联。键和映射值的类型可能不同。

  3. 在内部,unordered_map没有对按照任何特定的顺序排序, 为了能在常数范围内 找到key所对应的value,unordered_map将相同哈希值的键值对放在相同的桶中。

  4. unordered_map容器通过key访问单个元素要比map快,但它通常在遍历元素子集的范围迭 代方面效率较低。

  5. unordered_maps实现了直接访问操作符(operator[]),它允许使用key作为参数直接访问 value。

  6. 它的迭代器至少是前向迭代器。

unordered_map的接口说明

unordered_map的构造

unordered_map的定义方式

方式一: 指定key和value的类型构造一个空容器。

cpp 复制代码
unordered_map<int, double> um1; //构造一个key为int类型,value为double类型的空容器

方式二: 拷贝构造某同类型容器的复制品。

cpp 复制代码
unordered_map<int, double> um2(um1); //拷贝构造同类型容器um1的复制品

方式三: 使用迭代器拷贝构造某一段内容。

cpp 复制代码
//使用迭代器区间构造
string str = "nxbw";
unordered_map<int, double> mp3(str.begin(), str.end());

unordered_map接口的使用

unordered_map的容量

bool empty() const 检测unordered_map是否为空

cpp 复制代码
unordered_map<int, string> mp1;
mp1.emplace(1, "111");
cout << mp1.empty() << endl; // 0

unordered_map<int, string> mp2;
cout << mp2.empty() << endl; // 1 

size_t size() const 获取unordered_map的有效元素个数

cpp 复制代码
unordered_map<int, string> mp1;
mp1.emplace(1, "111");
mp1.emplace(2, "111");
mp1.emplace(3, "111");

cout << mp1.size() << endl; // 3

unordered_map的迭代器

begin返回unordered_map第一个元素的迭代器

cpp 复制代码
unordered_map<int, string> mp1;

unordered_map<int, string>::iterator it = mp1.begin();

mp1.emplace(1, "111");
mp1.emplace(2, "111");
mp1.emplace(3, "111");

cout << it->first << ' ' << it->second << endl; // 1 111

end返回unordered_map最后一个元素下一个位置的迭代器

cpp 复制代码
unordered_map<int, string> mp1;
mp1.emplace(1, "111");
mp1.emplace(2, "111");
mp1.emplace(3, "222");
	
unordered_map<int, string>::iterator it = mp1.end();
--it;
cout << it->first << ' ' << it->second << endl;

cbegin 返回unordered_map第一个元素的const迭代器

cend返回unordered_map最后一个元素下一个位置的const迭代器

unordered_map的元素访问

**operator[]**返回与key对应的value,没有一个默认值

注意:该函数中实际调用哈希桶的插入操作,用参数key与V()构造一个默认值往底层哈希桶 中插入,如果key不在哈希桶中,插入成功,返回V(),插入失败,说明key已经在哈希桶中, 将key对应的value返回。

cpp 复制代码
unordered_map<int, string> mp1;
mp1.emplace(1, "111");
mp1.emplace(2, "111");
mp1.emplace(3, "222");

cout << mp1[1] << endl; // 111
mp1[1] = "333";
cout << mp1[1] << endl; // 333

mp1[4] = "888";
cout << mp1[4] << endl; //插入4,并返回888

unordered_map的查询

iterator find(const K& key) 返回key在哈希桶中的位置

cpp 复制代码
unordered_map<int, string> mp1;
mp1.emplace(1, "111");
mp1.emplace(2, "222");
mp1.emplace(3, "333");

//找到返回该位置的迭代器,否则返回end()迭代器
unordered_map<int, string>::iterator it = mp1.find(1);
cout << it->first << it->second << endl;

if (mp1.find(4) == mp1.end()) cout << "find fail!" << endl;

size_t count(const K& key) 返回哈希桶中关键码为key的键值对的个数

cpp 复制代码
unordered_map<int, string> mp1;
mp1.emplace(1, "111");
mp1.emplace(2, "222");
mp1.emplace(3, "333");
mp1.emplace(4, "333");
mp1.emplace(5, "333");

cout << mp1.count(2) << endl; //找到返回1,否则返回0

unordered_map的修改操作

insert 向容器中插入键值对

cpp 复制代码
unordered_map<int, string> mp1;
mp1.insert(make_pair(1, "111"));
mp1.insert(make_pair(2, "111"));
mp1.insert(make_pair(3, "111"));
    
for (const auto& e : mp1)
{
	cout << e.first << ' ' << e.second << endl;
}

erase 删除容器中的键值对

cpp 复制代码
mp1.erase(1);
mp1.erase(2);

for (const auto& e : mp1)
{
	cout << e.first << ' ' << e.second << endl;
}

void clear() 清空容器中有效元素个数

cpp 复制代码
unordered_map<int, string> mp1;
mp1.insert(make_pair(1, "111"));
mp1.insert(make_pair(2, "111"));
mp1.insert(make_pair(3, "111"));

mp1.clear();
cout << mp1.empty() << endl; // 1

void swap(unordered_map&) 交换两个容器中的元素

cpp 复制代码
unordered_map<int, string> mp1;
mp1.insert(make_pair(1, "111"));
mp1.insert(make_pair(2, "222"));
mp1.insert(make_pair(3, "333"));

unordered_map<int, string> mp2;
mp2.insert(make_pair(4, "444"));
mp2.insert(make_pair(5, "555"));
mp2.insert(make_pair(6, "666"));

mp1.swap(mp2);

cout << "mp1: " << endl;
for (const auto& e : mp1)
{
	cout << e.first << ' ' << e.second << endl;
}

cout << "mp2: " << endl;
for (const auto& e : mp2)
{
	cout << e.first << ' ' << e.second << endl;
}

unordered_multimap

unordered_multimap容器与unordered_map容器的底层数据结构是一样的,都是哈希表,其次,它们所提供的成员函数的接口都是基本一致的,这里就不再列举了,这两种容器唯一的区别就是,unordered_multimap容器允许键值冗余,即unordered_multimap容器当中存储的键值对的key值是可以重复的。

cpp 复制代码
unordered_multimap<int, string> mp;
mp.emplace(1, "111");
mp.emplace(2, "111");
mp.emplace(3, "111");
mp.emplace(2, "111");
mp.emplace(3, "111");

for (const auto& e : mp)
{
	cout << e.first << ' ' << e.second << ' ';
}

由于unordered_multimap容器允许键值对的键值冗余,因此该容器中成员函数find和count的意义与unordered_map容器中的也有所不同:

成员函数find 功能
unordered_map容器 返回键值为key的键值对的迭代器
unordered_multimap容器 返回底层哈希表中第一个找到的键值为key的键值对的迭代器
成员函数count 功能
unordered_map容器 键值为key的键值对存在则返回1,不存在则返回0(find成员函数可替代)
unordered_multimap容器 返回键值为key的键值对的个数(find成员函数不可替代)

其次,由于unordered_multimap容器允许键值对的键值冗余,调用[ ]运算符重载函数时,应该返回键值为key的哪一个键值对的value的引用存在歧义,因此在unordered_multimap容器当中没有实现[ ]运算符重载函数。

unordered_set

在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时的效率可达到O ( l o g N ) O(logN)O(logN),即最差情况下需要比较红黑树的高度次,当树中的结点非常多时,查询效率也不理想。最好的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同。

unordered_set的定义方式

方式一: 构造一个某类型的空容器。

cpp 复制代码
unordered_set<int> us1; //构造int类型的空容器

方式二: 拷贝构造某同类型容器的复制品。

cpp 复制代码
unordered_set<int> us2(us1); //拷贝构造同类型容器us1的复制品

方式三: 使用迭代器拷贝构造某一段内容。

cpp 复制代码
string str("abcedf");
unordered_set<char> us3(str.begin(), str.end()); //构造string对象某段区间的复制品

unordered_set的接口使用

unordered_set当中常用的成员函数如下:

成员函数 功能
insert 插入指定元素
erase 删除指定元素
find 查找指定元素
size 获取容器中元素的个数
empty 判断容器是否为空
clear 清空容器
swap 交换两个容器中的数据
count 获取容器中指定元素值的元素个数

unordered_set当中迭代器相关函数如下:

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

使用示例:

cpp 复制代码
int main()
{
	unordered_set<int> st;
	st.insert(1);
	st.insert(4);
	st.insert(4);
	st.insert(2);
	st.insert(3);
	st.insert(2);

	//去重 遍历容器元素方式一
	for (const auto& e : st)
	{
		cout << e << ' '; // 1 4 2 3
	}
	cout << endl;

	//删除元素方式一 使用key值
	st.erase(1);
	//删除元素方式二 使用迭代器
	unordered_set<int>::iterator it = st.find(1);
	if (it != st.end())
	{
		st.erase(it);
	}

	//遍历容器元素方式二
	unordered_set<int>::iterator it = st.begin();
	while(it != st.end())
	{
		cout << *it << ' '; //1 4 3 2
		it++;
 	}
	cout << endl;

	//容器中值为2的元素
	cout << st.count(2) << endl;
	//容器大小
	cout << st.size() << endl;
	//判断容器是否为空,为空返回真,否则假
	cout << st.empty() << endl;

	//交换两个容器的数据
	unordered_set<int> rst( {5, 4, 6, 7} );
	rst.swap(rst);
	for (const auto& e : rst)
	{
		cout << e << ' ';
	}
	cout << endl;

	return 0;
}

unordered_multiset

unordered_multiset容器与unordered_set容器的底层数据结构是一样的,都是哈希表,其次,它们所提供的成员函数的接口都是基本一致的,这里就不再列举了,这两种容器唯一的区别就是,unordered_multiset容器允许键值冗余,即unordered_multiset容器当中存储的元素是可以重复的。

cpp 复制代码
unordered_multiset<int> st;
st.insert(1);
st.insert(1);
st.insert(2);
st.insert(2);
st.insert(3);
st.insert(3);

for (const auto& e : st)
{
	cout << e << ' '; // 1 1 2 2 3 3
}
cout << endl;

由于unordered_multimap容器允许键值对的键值冗余,因此该容器中成员函数find和count的意义与unordered_map容器中的也有所不同:

成员函数find 功能
unordered_map容器 返回键值为key的键值对的迭代器
unordered_multimap容器 返回底层哈希表中第一个找到的键值为key的键值对的迭代器
成员函数count 功能
unordered_map容器 键值为key的键值对存在则返回1,不存在则返回0(find成员函数可替代)
unordered_multimap容器 返回键值为key的键值对的个数(find成员函数不可替代)

其次,由于unordered_multimap容器允许键值对的键值冗余,调用[ ]运算符重载函数时,应该返回键值为key的哪一个键值对的value的引用存在歧义,因此在unordered_multimap容器当中没有实现[ ]运算符重载函数。

相关推荐
水水沝淼㵘2 分钟前
嵌入式开发学习日志(数据结构--单链表)Day20
c语言·开发语言·数据结构·学习·算法
举一个梨子zz3 分钟前
Java—— 可变参数、集合工具类、集合嵌套、不可变集合
java·开发语言·intellij-idea·需求分析
iangyu7 分钟前
【windows server脚本每天从网络盘复制到本地】
开发语言·windows·php
程序员拂雨14 分钟前
Python知识框架
开发语言·python
泽020221 分钟前
C++类和对象之相关特性
java·开发语言·c++
敲键盘的小夜猫27 分钟前
深入理解Python逻辑判断、循环与推导式(附实战案例)
开发语言·python
feiyangqingyun1 小时前
Qt/C++开发监控GB28181系统/录像文件查询/录像回放/倍速播放/录像文件下载
c++·qt·gb28181·录像回放·录像文件下载
2301_807611491 小时前
310. 最小高度树
c++·算法·leetcode·深度优先·回溯
为自己_带盐1 小时前
浅聊一下数据库的索引优化
开发语言·数据库·php
明月看潮生2 小时前
青少年编程与数学 02-019 Rust 编程基础 12课题、所有权系统
开发语言·青少年编程·rust·编程与数学