如果写了unordered_map< pair ... ,会报奇怪的错误:
但是换成map就好了。
------------------
unordered_map:
unordered_map
的键值类型可以是 pair
,但在使用时需要注意一些问题。让我来解释一下:
-
自定义哈希函数 :由于
unordered_map
默认不支持pair
作为键值,你需要提供一个哈希函数来告诉编译器如何计算pair
类型的哈希值。你可以通过重载std::hash
模板来实现这一点。 -
定义哈希函数 :你可以自己定义一个哈希函数,用于计算
pair
类型的哈希值。这个哈希函数应该接受一个pair
类型的参数,并返回一个size_t
类型的哈希值。 -
注意
std::pair
的哈希函数 :C++11 提供了std::hash
模板的特化版本用于std::pair
,但你需要确保std::hash
已经包含在你的头文件中。
下面是一个示例,展示了如何定义一个哈希函数来支持 pair
作为 unordered_map
的键值:
(注意是重写unordered_map的第三个模板参数(哈希函数类型))
(
具体来说,在 unordered_map<Key, T, Hash, KeyEqual, Allocator>
中:
Key
是键类型。T
是值类型。Hash
是哈希函数类型。KeyEqual
是键相等比较器类型(默认为std::equal_to<Key>
)。Allocator
是分配器类型(默认为std::allocator<std::pair<const Key, T>>
)。
)
#include <iostream>
#include <unordered_map>
using namespace std;
// 自定义哈希函数
struct pair_hash {
template <class T1, class T2>
size_t operator () (const pair<T1,T2> &p) const {
auto h1 = hash<T1>{}(p.first);
auto h2 = hash<T2>{}(p.second);
return h1 ^ h2; // 哈希组合
}
};
int main() {
unordered_map<pair<int, int>, int, pair_hash> myMap;
// 添加键值对
myMap[make_pair(1, 2)] = 10;
myMap[make_pair(3, 4)] = 20;
// 访问键值对
cout << myMap[make_pair(1, 2)] << endl; // 输出 10
cout << myMap[make_pair(3, 4)] << endl; // 输出 20
return 0;
}
在这个示例中,我们定义了一个名为 pair_hash
的结构体,重载了 operator()
来计算 pair
类型的哈希值。然后在定义 unordered_map
时,指定了这个自定义的哈希函数。
------------------
map:
map
可以使用 pair
作为键值,而不需要额外定义哈希函数。这是因为 map
使用红黑树(Red-Black Tree)来实现,而不是哈希表。
红黑树是一种自平衡二叉搜索树,它在插入和删除操作时通过一系列旋转和颜色变换来保持树的平衡,从而保证了插入、删除和搜索的时间复杂度都是 O(log n)。
在 map
中,pair
的比较方式取决于 pair
中两个元素的比较方式。具体来说,map
会根据 pair
的第一个元素进行比较,如果第一个元素相等,则比较第二个元素。 所以,pair
的比较不是简单地将两个元素相加,而是按照元素的大小依次比较。
例如,对于 pair<int, int>
类型的键值,map
会按照先比较第一个整数,如果相等再比较第二个整数。