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
: 返回容器的迭代器,用于遍历容器中的所有元素。begin
和end
返回非常量迭代器,cbegin
和cend
返回常量迭代器。
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 提供的成员函数来操作和管理容器中的元素。