哈希表(Hash Table)是一种重要的数据结构,能够以近乎常数的时间复杂度进行插入、删除和查找操作。在 C++ 标准模板库(STL)中,unordered_map
和 unordered_set
提供了哈希表的实现。本文将详细介绍 C++ STL 中哈希表的用法,包括基本操作、常见应用场景及注意事项。
一、基本概念
哈希表是一种使用键-值对(key-value pair)存储数据的数据结构。通过哈希函数将键映射到特定的桶(bucket),从而加快查找速度。STL 提供了两种哈希表实现:
unordered_map
:用于存储键-值对。unordered_set
:用于存储唯一的键。
二、unordered_map
用法
unordered_map
是一种基于哈希表的关联容器,允许快速查找、插入和删除元素。其常见操作如下:
1.初始化和插入元素
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap;
// 插入元素
umap["apple"] = 1;
umap["banana"] = 2;
umap.insert({"cherry", 3});
// 遍历输出元素
for (const auto &pair : umap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
2.查找元素
// 查找元素
auto it = umap.find("banana");
if (it != umap.end()) {
std::cout << "Found: " << it->first << " => " << it->second << std::endl;
} else {
std::cout << "Element not found" << std::endl;
}
3.删除元素
// 删除元素
umap.erase("apple");
4.检查元素是否存在
if (umap.count("banana")) {
std::cout << "Element exists" << std::endl;
}
5.获取元素数量
std::cout << "Size: " << umap.size() << std::endl;
三、unordered_set
用法
unordered_set
也是一种基于哈希表的容器,但它只存储唯一的键,没有值。其常见操作如下:
1.初始化和插入元素
#include <iostream>
#include <unordered_set>
int main() {
std::unordered_set<int> uset = {1, 2, 3};
// 插入元素
uset.insert(4);
// 遍历输出元素
for (const auto &elem : uset) {
std::cout << elem << std::endl;
}
return 0;
}
2.查找元素
// 查找元素
if (uset.find(2) != uset.end()) {
std::cout << "Found 2" << std::endl;
}
3.删除元素
// 删除元素
uset.erase(3);
4.检查元素是否存在
if (uset.count(1)) {
std::cout << "Element exists" << std::endl;
}
5.获取元素数量
std::cout << "Size: " << uset.size() << std::endl;
四、注意事项
-
哈希函数和等价判断 默认情况下,
unordered_map
和unordered_set
使用std::hash
函数和==
运算符进行哈希计算和键的比较。如果需要自定义哈希函数和等价判断,可以通过模板参数实现。 -
负载因子和重哈希 当元素数量超过一定阈值时,哈希表会进行重哈希操作,这会重新分配桶并移动元素,导致性能波动。可以使用
rehash
方法手动控制重哈希行为。 -
迭代器稳定性 重哈希操作会使迭代器失效,插入和删除操作也可能导致迭代器失效,因此在迭代过程中需要谨慎操作。
五、应用场景
- 字数统计 使用
unordered_map
统计文档中每个单词出现的次数。
#include <iostream>
#include <unordered_map>
#include <sstream>
#include <string>
int main() {
std::unordered_map<std::string, int> wordCount;
std::string text = "this is a test. This test is only a test.";
std::istringstream stream(text);
std::string word;
while (stream >> word) {
++wordCount[word];
}
for (const auto &pair : wordCount) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
2.唯一性检查 使用 unordered_set
检查集合中的元素是否唯一。
#include <iostream>
#include <unordered_set>
int main() {
std::unordered_set<int> uset = {1, 2, 3, 4, 5};
if (uset.count(3)) {
std::cout << "Element 3 exists" << std::endl;
} else {
std::cout << "Element 3 does not exist" << std::endl;
}
return 0;
}
六、总结
C++ STL 中的 unordered_map
和 unordered_set
提供了强大的哈希表功能,能够高效地进行插入、删除和查找操作。理解其用法和注意事项,能够帮助我们在实际开发中更好地利用这些容器。