unordered_map总结

1、简单介绍

unordered_map是C++标准库中的一个关联容器,它允许通过键值对(key-value pairs)进行存储和查询。与std::map相比,unordered_map不会根据键自动排序,而是使用哈希表(hash table)进行存储,从而提供了平均时间复杂度为O(1)的快速查找、插入和删除操作。

使用unordered_map时,需要包含头文件#include <unordered_map>。unordered_map的声明为:

std::unordered_map<Key, T, Hash, KeyEqual, Allocator>

其中:

Key: 键的类型。

T: 值的类型。

Hash: 哈希函数对象类型。它用于计算键的哈希值。默认情况下,C++标准库提供了std::hash模板,支持基本数据类型和一些标准库类型的哈希计算。如果需要为自定义类型计算哈希值,可以提供自定义的哈希函数对象。

KeyEqual: 键比较函数对象类型。它用于比较两个键是否相等。默认情况下,使用operator==进行比较。

Allocator: 分配器类型。它用于管理unordered_map内存分配。默认情况下,使用std::allocator。

下面是unordered_map的简单示例:

#include <iostream>
#include <unordered_map>
#include <string>

int main() {
    std::unordered_map<std::string, int> word_count;

    // 插入键值对
    word_count["apple"] = 3;
    word_count["banana"] = 5;

    // 查询键值对
    std::cout << "apple: " << word_count["apple"] << std::endl;
    std::cout << "banana: " << word_count["banana"] << std::endl;

    // 更新键值对
    word_count["apple"] += 2;

    // 删除键值对
    word_count.erase("banana");

    return 0;
}

2、构造函数

std::unordered_map 提供了一系列构造函数,以便在不同的场景下创建和初始化容器。以下是一些常用的构造函数:

①默认构造函数:创建一个空的 unordered_map 容器。

std::unordered_map<Key, T> map;

②拷贝构造函数:创建一个新的 unordered_map 容器,其内容为另一个 unordered_map 容器的副本。

std::unordered_map<Key, T> map1;
// ... 填充 map1
std::unordered_map<Key, T> map2(map1);

3、移动构造函数:创建一个新的 unordered_map 容器,将另一个 unordered_map 容器的内容移动到新容器中。原容器的内容将被清空。

std::unordered_map<Key, T> map1;
// ... 填充 map1
std::unordered_map<Key, T> map2(std::move(map1));

4、初始化列表构造函数:使用初始化列表创建并初始化 unordered_map 容器。

std::unordered_map<std::string, int> map = {
   
   {"apple", 3}, {"banana", 5}, {"orange", 2}};

5、范围构造函数:使用迭代器范围创建并初始化 unordered_map 容器。

std::vector<std::pair<std::string, int>> vec = {
   
   {"apple", 3}, {"banana", 5}, {"orange", 2}};
std::unordered_map<std::string, int> map(vec.begin(), vec.end());

6、自定义哈希和键比较函数的构造函数:创建一个空的 unordered_map 容器,指定自定义的哈希函数和键比较函数。

struct CustomHash {
    std::size_t operator()(const Key& key) const {
        // 计算 key 的哈希值
    }
};

struct CustomKeyEqual {
    bool operator()(const Key& lhs, const Key& rhs) const {
        // 比较两个键是否相等
    }
};

std::unordered_map<Key, T, CustomHash, CustomKeyEqual> map;

这些构造函数可以根据需要组合使用,以满足创建和初始化 unordered_map 容器的需求。同时,还可以在构造函数中指定桶数量和分配器,以实现更高的性能和自定义内存管理。

3、成员函数

unordered_map提供了一系列成员函数,用于操作和管理键值对。下面是一些常用的成员函数:

1)operator[]: 根据给定的键查找值,如果键不存在,则插入一个具有该键和默认初始化值的新元素。

unordered_map<Key, T> map;
map[key] = value;

2)at: 根据给定的键查找值,如果键不存在,抛出std::out_of_range异常。

try {
    value = map.at(key);
} catch (const std::out_of_range& e) {
    std::cout << "Key not found: " << e.what() << std::endl;
}

3)insert: 向容器中插入一个或多个键值对。如果键已存在,则插入失败。

std::pair<iterator, bool> result = map.insert({key, value});

4)emplace: 与insert类似,但使用构造函数直接在容器中构造键值对,避免了临时对象的创建和拷贝。

std::pair<iterator, bool> result = map.emplace(key, value);

5)erase: 删除容器中与给定键匹配的元素。

map.erase(key);

6)find: 查找给定键的元素,如果找到,则返回一个指向该元素的迭代器,否则返回指向容器end的迭代器。

auto it = map.find(key);
if (it != map.end()) {
    // key found
} else {
    // key not found
}

7)count: 返回给定键的元素数量(0或1,因为键在unordered_map中是唯一的)。

if (map.count(key) > 0) {
    // key exists
} else {
    // key does not exist
}

8)size: 返回容器中元素的数量。

std::size_t size = map.size();

9)empty: 判断容器是否为空。

if (map.empty()) {
    // container is empty
} else {
    // container is not empty
}

10)clear: 清除容器中的所有元素。

map.clear();

11)begin, end, cbegin, cend: 返回容器的迭代器,用于遍历容器中的所有元素。beginend返回非常量迭代器,cbegincend返回常量迭代器。

for (auto it = map.begin(); it != map.end(); ++it) {
    std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl;
}

4、成员变量

std::unordered_map 是一个容器类,它的实现会根据具体的编译器和标准库版本有所差异。unordered_map 的内部成员变量通常包含以下几部分:

1)哈希表:unordered_map 的基础数据结构。哈希表由一定数量的桶组成,每个桶存储一个键值对链表。哈希表用于将键的哈希值映射到对应的桶。

2)键类型(Key):用于存储键的数据类型。

3)值类型(T):用于存储值的数据类型。

4)哈希函数对象(Hash):用于计算键的哈希值。默认情况下,C++ 标准库提供了 std::hash 模板,支持基本数据类型和一些标准库类型的哈希计算。用户可以提供自定义的哈希函数对象。

5)键比较函数对象(KeyEqual):用于比较两个键是否相等。默认情况下,使用 operator== 进行比较。用户可以提供自定义的键比较函数对象。

6)分配器(Allocator):用于管理 unordered_map 内存分配。默认情况下,使用 std::allocator。用户可以提供自定义的分配器。

7)元素数量(size):记录容器中存储的元素个数。

注意,unordered_map 的内部成员变量对用户是不可见的,因此不能直接访问这些成员变量。用户可以通过 unordered_map 提供的成员函数来操作和管理容器中的元素。

猜你喜欢

转载自blog.csdn.net/2201_75772333/article/details/130605751