1. 简介
unordered_map是一种关联式容器,包含唯一的键值对,即 (key, value);增加、修改和查询具有线性的时间复杂度,其存储结构为哈希;元素的存储并未按照特定的顺序,而是被组织到桶中,在哪个桶中取决于其散列值;
头文件和定义
#include <unordered_map>
template<
class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;
2. 初始化
unordered_map初始化的方式如下所示:
/*
* @brief: unordered_map
* @compile: g++ -g unordered_map_main.cc -o d -std=c++11
* @author: your name
* @date: 2023/03/27
* @lastEditorDate:
*/
#include <iostream>
#include <unordered_map>
#include <string>
#include <iterator>
template<typename T>
void showInfo(T &t)
{
for(const auto& au : t)
{
std::cout<<"["<<au.first<<" ,"<<au.second<<"]; ";
}
std::cout<<"\n\n";
}
int main(int argc, char *argv[])
{
//直接初始化
std::unordered_map<int32_t, std::string> un_m1{
{
4, "c"},{
2, "c"},{
3, "c"},{
7, "c"},{
5, "c"}};
showInfo(un_m1);
std::unordered_map<int32_t, std::string> un_m2;
un_m2[1] = "teacher";
un_m2.insert(std::make_pair(3, "student"));
un_m2.emplace(std::make_pair(5, "boy"));
un_m2.insert(std::pair<int32_t, std::string>(9, "girl"));
showInfo(un_m2);
//拷贝初始化
std::unordered_map<int32_t, std::string> un_m3 = un_m2;
showInfo(un_m3);
return 0;
}
输出
[5 ,c]; [7 ,c]; [3 ,c]; [2 ,c]; [4 ,c];
[9 ,girl]; [5 ,boy]; [1 ,teacher]; [3 ,student];
[9 ,girl]; [5 ,boy]; [1 ,teacher]; [3 ,student];
3. 使用
3.1 元素的访问
3.1 元素访问
方法 | 说明 |
---|---|
at() | 下标访问 |
operator[] | 下标访问 |
iterator | 字典元素的遍历 |
#include <iostream>
#include <unordered_map>
#include <string>
#include <iterator>
#include <functional>
using sstring = std::string;
//auto eend = std::cout<<std::endl;
void printEnd(int32_t n)
{
for(int32_t i = 0; i < n; i++){
std::cout<<std::endl;}
}
std::function<void(int32_t)> end = printEnd;
template<typename T>
void showInfo(T &t)
{
for(const auto& au : t)
{
std::cout<<"["<<au.first<<" ,"<<au.second<<"]; ";
}
}
int main(int argc, char *argv[])
{
//at operator[] 迭代器
std::unordered_map<sstring, sstring> un_m1{
{
"1", "c"},{
"2", "c++"},{
"3", "R"},{
"7", "Rust"},{
"5", "python"}};
showInfo(un_m1);
end(1);
std::cout<<"at() "<<un_m1.at("2");end(1);
std::cout<<"operator[] "<<un_m1["7"];end(1);
auto iter = un_m1.begin();
std::cout<<iter->first<<" "<<iter->second;
end(1);
return 0;
}
输出
[7 ,Rust]; [3 ,R]; [2 ,c++]; [5 ,python]; [1 ,c];
at() c++
operator[] Rust
7 Rust
3.2 字典的大小
方法 | 说明 |
---|---|
empty | 字典判空 |
size | 字典大小 |
max_size | 最大容量 |
clear | 清空unordered_map的大小 |
swap | 交换两个unordered_map的内容 |
示例
int main(int argc, char *argv[])
{
//empty size max_size clear swap
std::unordered_map<sstring, sstring> un_m1{
{
"1", "c"},{
"2", "c++"},{
"3", "R"},{
"7", "Rust"},{
"5", "python"}};
std::unordered_map<sstring, sstring> un_m2{
{
"1", "student"},{
"2", "teacher"},{
"3", "boy"},{
"7", "girl"}};
std::cout<<"[un_m1]";end(1);
showInfo(un_m1);end(1);
std::cout<<"[un_m2]";end(1);
showInfo(un_m2); end(2);
std::cout<<"size() "<<un_m1.size();end(1);
std::cout<<"max_size() "<<un_m1.max_size();end(1);
std::cout<<"[swap]"; end(1);
un_m1.swap(un_m2);
std::cout<<"[un_m1]"; end(1);
showInfo(un_m1); end(1);
std::cout<<"[un_m2]";end(1);
showInfo(un_m2);end(2);
un_m1.clear();
if(un_m1.empty())
{
std::cout<<"un_m1 empty()";end(1);
}
else{
std::cout<<"un_m1 not empty()";end(1);
}
return 0;
}
输出
[un_m1]
[7 ,Rust]; [3 ,R]; [2 ,c++]; [5 ,python]; [1 ,c];
[un_m2]
[7 ,girl]; [3 ,boy]; [2 ,teacher]; [1 ,student];
size() 5
max_size() 230584300921369395
[swap]
[un_m1]
[7 ,girl]; [3 ,boy]; [2 ,teacher]; [1 ,student];
[un_m2]
[7 ,Rust]; [3 ,R]; [2 ,c++]; [5 ,python]; [1 ,c];
un_m1 empty()
3.3 元素的修改
方法 | 说明 |
---|---|
= | 直接赋值 |
get_allocator | 返回内存分配器 |
insert | 插入元素,key值相同则不插入 |
insert_or_assign (C++17) | 插入元素,元素存在则替换,不在则新增;支持直接插入元素 |
emplace | 插入元素 |
emplace_hint | 插入元素,需要添加位置 |
try_emplace(C++17) | 插入元素,需要添加位置 |
erase | 删除元素 |
extract(C++17) | 元素的删除,可以返回该值 |
merge(C++17) | unordered_map的合并 |
示例
int main(int argc, char *argv[])
{
//operator= get_allocator insert insert_or_assign emplace emplace_hint try_emplace erase extract merge
//1.数据插入
std::unordered_map<sstring, sstring> un_m1{
{
"1", "c"}};
un_m1.insert(std::make_pair("2", "c++"));
un_m1["11"] = "matlab"; //operator=
auto au = un_m1.insert_or_assign("2", "python"); //新增则返回1,否则返回0;不需要make_pair
std::cout<<au.second;end(1);
un_m1.emplace(std::make_pair("3", "R"));
un_m1.emplace_hint(un_m1.begin(), std::make_pair("7", "Rust"));
un_m1.try_emplace("9", "linux"); //不需要make_pair
showInfo(un_m1);end(2);
//2.数据删除
un_m1.erase("7");
un_m1.erase(un_m1.begin());
showInfo(un_m1);end(2);
//3.extract(删除) merge(合并)
un_m1.extract(un_m1.begin());
un_m1.extract("2");
showInfo(un_m1);end(1);
std::unordered_map<sstring, sstring> un_m2{
{
"1", "student"},{
"2", "teacher"},{
"3", "boy"},{
"7", "girl"}};
un_m1.merge(un_m2);
showInfo(un_m1);end(1);
return 0;
}
输出
0
[9 ,linux]; [7 ,Rust]; [1 ,c]; [2 ,python]; [11 ,matlab]; [3 ,R];
[1 ,c]; [2 ,python]; [11 ,matlab]; [3 ,R];
[11 ,matlab]; [3 ,R];
[1 ,student]; [7 ,girl]; [2 ,teacher]; [11 ,matlab]; [3 ,R];
3.4 元素的操作
桶是内部的存储结构
方法 | 说明 |
---|---|
count | 计算unordered_map中元素出现的次数 |
find | 查找元素 |
equal_range | 返回的是一个范围 [lower_bound, upper_bound] |
bucket_count | 返回桶的数量 |
max_bucket_count | 返回桶可以达到的最大数量 |
bucket_size(n) | 返回第n个桶中元素的数量 |
bucket | 返回元素在第几个桶中 |
load_factor | 返回桶的平均元素数 |
max_load_factor | 返回最大负载系数 |
rehash(n) | 设定桶的数目为n |
reserve(n) | 设定桶的数目最少为n |
hash_function | 返回一个唯一的大小为size_t的值 |
key_eq | 返回unordered_map使用的键等效项比较谓词 |
示例
扫描二维码关注公众号,回复:
15434426 查看本文章
int main(int argc, char *argv[])
{
//1.统计和查找
std::unordered_map<sstring, sstring> un_m1{
{
"1", "c"}, {
"3", "c++"}, {
"5", "matlab"}, {
"7", "linux"}, {
"10", "Rust"}};
showInfo(un_m1);end(1);
std::cout<<"count() is: "<<un_m1.count("3");end(2);
auto iter_find = un_m1.find("7");
std::cout<<iter_find->first<<" "<<iter_find->second;end(2);
auto iter_equal = un_m1.equal_range("5");
std::cout<<iter_equal.first->first<<" "<<iter_equal.first->second;end(1);
std::cout<<iter_equal.second->first<<" "<<iter_equal.second->second;end(2);
//2.桶相关的操作
std::cout<<"bucket_count() value is: "<<un_m1.bucket_count();end(1); //桶的数量
std::cout<<"max_bucket_count() value is: "<<un_m1.max_bucket_count();end(1); //桶的最大数量
std::cout<<"bucket_size(3) value is: "<<un_m1.bucket_size(3);end(1); //第3个桶中元素的数量
std::cout<<R"(bucket("10") value is: )"<<un_m1.bucket("3");end(1); //key("10")在第几个桶中
return 0;
}
输出
[10 ,Rust]; [7 ,linux]; [3 ,c++]; [5 ,matlab]; [1 ,c];
count() is: 1
7 linux
5 matlab
1 c
bucket_count() value is: 7
max_bucket_count() value is: 230584300921369395
bucket_size(3) value is: 2
bucket("10") value is: 6
3.5 迭代器
迭代器最好结合STL中的算法一起使用;迭代器的返回值最好用auto接收;
迭代器的类型包括:iterator和const_iterator
方法 | 说明 |
---|---|
begin | 返回unordered_map的头元素(迭代器),其值可修改 |
end | 返回unordered_map的尾元素(迭代器),其值可修改 |
cbegin | 返回unordered_map的头元素(迭代器),其值不可修改,const属性 |
cend | 返回unordered_map的尾元素(迭代器),其值不可修改,const属性 |
迭代器的辅助函数
辅助函数的使用需要包含头文件
#include <iterator>
方法 | 说明 |
---|---|
advance | 移动迭代器的位置 |
distance | 计算两个迭代器的距离 |
begin | 返回容器第一个元素的迭代器 |
end | 返回容器最后一个元素的迭代器 |
prev | 迭代器向前移动一个元素 |
next | 迭代器向后移动一个元素 |