如何在C++中高效使用unordered_map
unordered_map 是 C++ STL 中的一种 Associative Container,它使用哈希表存储元素,可以提供高效的查找、插入和删除操作。下面将介绍在 C++ 中如何正确高效地使用 unordered_map 。
1. unordered_map的声明
使用 unordered_map 需要包含头文件 <unordered_map>
,声明 unordered_map 的语法如下:
#include <unordered_map>
std::unordered_map<key_type, value_type> unordered_map_name;
其中,key_type
表示键的类型,value_type
表示值的类型,unordered_map_name
表示 unordered_map 的名称。
例如,声明一个 unordered_map 对象 my_map
,其键和值的类型都是 int
,可以这样写:
#include <unordered_map>
std::unordered_map<int, int> my_map;
2. 添加元素
向 unordered_map 中添加元素的方法也很简单,可以使用 insert() 函数或者像数组一样的下标操作符 []。对于键值对 (key, value)
,使用 insert() 函数的语法如下:
my_map.insert(std::make_pair(key, value));
或者简写为:
my_map.emplace(key, value);
使用下标操作符 [] 的语法如下:
my_map[key] = value;
例如:
std::unordered_map<int, std::string> my_map;
my_map.insert(std::make_pair(1, "one"));
my_map.emplace(2, "two");
my_map[3] = "three";
3. 删除元素
unordered_map 中删除元素的方法也很简单,可以使用 erase() 函数,传入键值对的键作为参数即可。例如:
std::unordered_map<int, std::string> my_map;
my_map.insert(std::make_pair(1, "one"));
my_map.emplace(2, "two");
my_map.erase(1);
4. 查找元素
unordered_map 查找元素的方法有很多种,下面介绍几种常用的方法:
4.1 find()
使用 find() 函数可以返回指向键所关联值的迭代器。如果键不存在,则返回 unordered_map::end()。例如:
std::unordered_map<int, std::string> my_map;
my_map.insert(std::make_pair(1, "one"));
my_map.emplace(2, "two");
auto it = my_map.find(1);
if (it != my_map.end()) {
std::cout << "Found value: " << it->second << std::endl;
} else {
std::cout << "Key not found" << std::endl;
}
4.2 count()
使用 count() 函数返回键的数量(0或1)。例如:
std::unordered_map<int, std::string> my_map;
my_map.insert(std::make_pair(1, "one"));
my_map.emplace(2, "two");
if (my_map.count(1)) {
std::cout << "Found key" << std::endl;
} else {
std::cout << "Key not found" << std::endl;
}
4.3 at()
使用 at() 函数返回与给定键关联的值。如果键不存在,则会抛出一个 out_of_range 异常。例如:
std::unordered_map<int, std::string> my_map;
my_map.insert(std::make_pair(1, "one"));
my_map.emplace(2, "two");
try {
std::cout << "Value for key 1: " << my_map.at(1) << std::endl;
std::cout << "Value for key 3: " << my_map.at(3) << std::endl;
} catch (const std::out_of_range& oor) {
std::cout << "Key not found" << std::endl;
}
5. 遍历元素
unordered_map 的遍历可以使用迭代器实现。例如:
std::unordered_map<int, std::string> my_map;
my_map.insert(std::make_pair(1, "one"));
my_map.emplace(2, "two");
for (const auto& pair : my_map) {
std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
}
6. unordered_map的性能
unordered_map 的性能与哈希函数有很大关系。为了最大限度地提高性能,应该选择合适的哈希函数和哈希表大小。C++ STL 中的 unordered_map 采用了 Robin Hood 哈希算法,可以提供很好的性能。
下面是 unordered_map 的常用操作的时间复杂度:
- 插入元素:平均时间复杂度为 O(1),最坏情况下为 O(n)
- 查找元素:平均时间复杂度为 O(1),最坏情况下为 O(n)
- 删除元素:平均时间复杂度为 O(1),最坏情况下为 O(n)
其中,n 表示 unordered_map 中元素的数量。
结论
使用 unordered_map 可以高效地实现对于键值对的增删查找操作。为了获得最佳性能,应该选择合适的哈希函数和哈希表大小。同时,需要注意 unordered_map 的 worst case 性能较差,应该在算法设计中避免出现这种情况。