1 Introduction
unordered_map is an associative container that contains unique key-value pairs, namely (key, value); adding, modifying, and querying have linear time complexity, and its storage structure is hash; elements are not stored in a specific order , but are organized into buckets, in which bucket depends on its hash value;
header files and definitions
#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. Initialization
The way unordered_map is initialized is as follows:
/*
* @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;
}
output
[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. use
3.1 Access to elements
3.1 Element access
method | illustrate |
---|---|
at() | subscript access |
operator[] | subscript access |
iterator | Iterating over dictionary elements |
#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;
}
output
[7 ,Rust]; [3 ,R]; [2 ,c++]; [5 ,python]; [1 ,c];
at() c++
operator[] Rust
7 Rust
3.2 The size of the dictionary
method | illustrate |
---|---|
empty | Dictionary is empty |
size | dictionary size |
max_size | Maximum capacity |
clear | Clear the size of unordered_map |
swap | Swap the contents of two unordered_maps |
example
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;
}
output
[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 Modification of elements
method | illustrate |
---|---|
= | direct assignment |
get_allocator | return memory allocator |
insert | Insert an element, if the key value is the same, it will not be inserted |
insert_or_assign (C++17) | Insert an element, replace it if the element exists, and add it if it does not exist; support direct insertion of elements |
place | insert element |
emplace_hint | To insert an element, you need to add a position |
try_emplace(C++17) | To insert an element, you need to add a position |
erase | delete element |
extract(C++17) | The deletion of the element can return this value |
merge(C++17) | Merge of unordered_map |
example
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;
}
output
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 Operation of elements
A bucket is an internal storage structure
method | illustrate |
---|---|
count | Count the number of occurrences of elements in unordered_map |
find | find element |
equal_range | Returns a range [lower_bound, upper_bound] |
bucket_count | Return the number of buckets |
max_bucket_count | Returns the maximum number of buckets that can be reached |
bucket_size(n) | Returns the number of elements in the nth bucket |
bucket | Which bucket the return element is in |
load_factor | Returns the average number of elements in a bucket |
max_load_factor | Returns the maximum load factor |
rehash(n) | Set the number of buckets to n |
reserve(n) | Set the number of buckets to at least n |
hash_function | 返回一个唯一的大小为size_t的值 |
key_eq | 返回unordered_map使用的键等效项比较谓词 |
示例
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 | 迭代器向后移动一个元素 |