**在 C++ 中,可以使用标准库中的
std::unordered_map和
std::unordered_set 来实现哈希表。这些容器提供了快速的插入、删除和查找操作。以下是一些简单的示例代码,展示如何使用这两个容器。**
使用 std::unordered_map
std::unordered_map
是一个键值对容器,其中每个键都是唯一的。
#include <iostream>
#include <unordered_map>
#include <string>
int main() {
// 创建一个unordered_map,键类型为std::string,值类型为int
std::unordered_map<std::string, int> hashMap;
// 插入键值对
hashMap["apple"] = 3;
hashMap["banana"] = 5;
hashMap["orange"] = 2;
// 查找一个键对应的值
std::string key = "banana";
if (hashMap.find(key) != hashMap.end()) {
std::cout << "The value for key " << key << " is " << hashMap[key] << std::endl;
} else {
std::cout << "Key " << key << " not found." << std::endl;
}
// 遍历所有的键值对
for (const auto& pair : hashMap) {
std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
}
return 0;
}
使用 std::unordered_set
std::unordered_set
是一个只包含唯一键的容器,没有对应的值。
#include <iostream>
#include <unordered_set>
int main() {
// 创建一个unordered_set,元素类型为int
std::unordered_set<int> hashSet;
// 插入元素
hashSet.insert(1);
hashSet.insert(2);
hashSet.insert(3);
// 查找一个元素
int value = 2;
if (hashSet.find(value) != hashSet.end()) {
std::cout << "Value " << value << " found in the set." << std::endl;
} else {
std::cout << "Value " << value << " not found in the set." << std::endl;
}
// 遍历所有的元素
for (const int& elem : hashSet) {
std::cout << "Element: " << elem << std::endl;
}
return 0;
}
选择哈希函数
默认情况下,std::unordered_map
和 std::unordered_set
使用标准库中的哈希函数。如果需要自定义哈希函数,可以通过模板参数指定。例如:
#include <iostream>
#include <unordered_map>
struct CustomHash {
std::size_t operator()(const std::pair<int, int>& p) const {
return std::hash<int>()(p.first) ^ (std::hash<int>()(p.second) << 1);
}
};
int main() {
// 创建一个使用自定义哈希函数的unordered_map
std::unordered_map<std::pair<int, int>, int, CustomHash> customHashMap;
// 插入键值对
customHashMap[{1, 2}] = 3;
customHashMap[{2, 3}] = 4;
// 查找一个键对应的值
std::pair<int, int> key = {1, 2};
if (customHashMap.find(key) != customHashMap.end()) {
std::cout << "The value for key (" << key.first << ", " << key.second << ") is " << customHashMap[key] << std::endl;
} else {
std::cout << "Key (" << key.first << ", " << key.second << ") not found." << std::endl;
}
return 0;
}
**这段代码定义了一个自定义哈希函数,用于计算
std::pair<int, int> 类型的哈希值。让我们详细解释每一部分的含义。**
std::size_t operator()(const std::pair<int, int>& p) const {
return std::hash<int>()(p.first) ^ (std::hash<int>()(p.second) << 1);
}
函数签名
std::size_t operator()(const std::pair<int, int>& p) const
std::size_t
: 这是返回类型,通常是一个无符号整数类型,用于表示哈希值。operator()
: 这是一个重载的函数调用运算符,使得这个结构体对象可以像函数一样被调用。const std::pair<int, int>& p
: 这是函数的参数,类型为const std::pair<int, int>&
,表示传入一个std::pair<int, int>
类型的常量引用。
函数体
return std::hash<int>()(p.first) ^ (std::hash<int>()(p.second) << 1);
std::hash<int>()(p.first)
:std::hash<int>
是标准库中的哈希函数对象,用于计算int
类型的哈希值。std::hash<int>()
创建一个临时的哈希函数对象,然后通过operator()
调用这个对象,计算p.first
的哈希值。std::hash<int>()(p.second)
: 同理,这部分计算p.second
的哈希值。^
: 这是按位异或运算符,用于将两个整数按位异或。异或运算有助于混合两个哈希值,从而减少哈希冲突。(std::hash<int>()(p.second) << 1)
: 这一部分计算p.second
的哈希值,然后将其左移 1 位。这相当于将哈希值乘以 2,起到了散列效果,使得组合后的哈希值更加独特。
总结
这段代码通过以下步骤计算一个 std::pair<int, int>
的哈希值:
- 计算
p.first
的哈希值。 - 计算
p.second
的哈希值,并将其左移 1 位。 - 将上述两个哈希值按位异或,得到最终的哈希值。
这个哈希函数结合了两个整数的哈希值,通过左移和异或运算,减少了哈希冲突,提高了哈希表的性能。
**
std::unordered_map和
std::unordered_set 是 C++ 标准库中的两个容器,分别用于存储键值对和唯一元素。以下是这两个容器的详细用法,包括它们的主要成员函数和一些常见操作的示例。**
std::unordered_map
用法
std::unordered_map
是一个关联容器,存储键值对,并允许通过键快速查找值。
主要成员函数
-
构造函数
std::unordered_map<Key, T> map; std::unordered_map<Key, T> map2 = { {key1, value1}, {key2, value2} };
-
插入元素
map.insert({key, value}); map[key] = value;
-
访问元素
map[key]; // 如果键不存在,会插入默认值 map.at(key); // 如果键不存在,会抛出异常
-
删除元素
map.erase(key); map.clear();
-
查找元素
auto it = map.find(key); if (it != map.end()) { // 键存在 }
-
其他操作
map.size(); // 返回元素数量 map.empty(); // 检查是否为空
示例代码
#include <iostream>
#include <unordered_map>
#include <string>
int main() {
std::unordered_map<std::string, int> map;
// 插入元素
map["apple"] = 3;
map.insert({"banana", 5});
// 访问元素
std::cout << "Apple: " << map["apple"] << std::endl;
try {
std::cout << "Banana: " << map.at("banana") << std::endl;
} catch (const std::out_of_range& e) {
std::cout << "Key not found: " << e.what() << std::endl;
}
// 查找元素
if (map.find("orange") == map.end()) {
std::cout << "Orange not found" << std::endl;
}
// 遍历元素
for (const auto& pair : map) {
std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
}
// 删除元素
map.erase("banana");
map.clear();
return 0;
}
std::unordered_set
用法
std::unordered_set
是一个集合容器,存储唯一元素。
主要成员函数
-
构造函数
std::unordered_set<T> set; std::unordered_set<T> set2 = { value1, value2, value3 };
-
插入元素
set.insert(value);
-
删除元素
set.erase(value); set.clear();
-
查找元素
auto it = set.find(value); if (it != set.end()) { // 元素存在 }
-
其他操作
set.size(); // 返回元素数量 set.empty(); // 检查是否为空
示例代码
#include <iostream>
#include <unordered_set>
int main() {
std::unordered_set<int> set;
// 插入元素
set.insert(1);
set.insert(2);
set.insert(3);
// 查找元素
if (set.find(2) != set.end()) {
std::cout << "2 found in the set" << std::endl;
} else {
std::cout << "2 not found in the set" << std::endl;
}
// 遍历元素
for (const auto& elem : set) {
std::cout << "Element: " << elem << std::endl;
}
// 删除元素
set.erase(2);
set.clear();
return 0;
}
在 C++ 中,
std::unordered_map的
find方法返回一个指向元素的迭代器,该迭代器指向包含指定键的键值对。如果你想通过迭代器来访问键值对,可以使用迭代器的
->first和
->second 成员来分别访问键和值。
以下是一个详细的示例,展示如何使用 std::unordered_map::find
来获取键值对,并访问其中的键和值:
#include <iostream>
#include <unordered_map>
#include <string>
int main() {
// 创建一个unordered_map,键类型为std::string,值类型为int
std::unordered_map<std::string, int> map;
// 插入一些键值对
map["apple"] = 3;
map["banana"] = 5;
map["orange"] = 2;
// 查找一个键对应的值
std::string key = "banana";
auto it = map.find(key);
if (it != map.end()) {
// 迭代器指向的键值对存在,可以通过it->first获取键,通过it->second获取值
std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl;
} else {
std::cout << "Key " << key << " not found." << std::endl;
}
// 遍历所有的键值对
for (auto it = map.begin(); it != map.end(); ++it) {
std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl;
}
return 0;
}
详细解释
-
插入键值对
map["apple"] = 3; map["banana"] = 5; map["orange"] = 2;
使用下标运算符插入一些键值对。
-
查找键并获取值
std::string key = "banana"; auto it = map.find(key);
使用
find
方法查找键"banana"
,返回一个指向该键值对的迭代器。 -
访问迭代器的键和值
if (it != map.end()) { std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl; }
通过
it->first
访问键,通过it->second
访问值。 -
遍历所有键值对
for (auto it = map.begin(); it != map.end(); ++it) { std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl; }
使用一个循环遍历
unordered_map
中的所有键值对,并通过迭代器访问每个键和值。
这种方法可以有效地查找和访问 unordered_map
中的元素,适用于需要快速查找和修改键值对的场景。