C++容器——字典(unordered_map)

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 迭代器向后移动一个元素

猜你喜欢

转载自blog.csdn.net/shouhu010/article/details/129795413