将参数传递给 unordered_map(或设置)哈希结构
Pass a parameter to an unordered_map (or set) hash struct
我有以下结构:
array<int, 2> map_size;
struct Node{
int id;
array<int, 2> pos;
vector<Node*> nbs;
bool in_open;
bool in_closed;
};
每个节点都有一个在 map_size(全局变量)范围内的位置 (pos)。
我正在使用以下无序映射
struct PosHash{
public:
size_t operator()(array<int, 2> const& pos) const{
return pos[1] + pos[0]*map_size[1];
}
};
struct PosCompare{
bool operator()(const array<int, 2>& pos1, const array<int, 2>& pos2) const{
if (pos1[0] == pos2[0] and pos1[1] == pos2[1]){
return true;
}
else{
return false;
}
}
};
unordered_map<array<int, 2>, Node*, PosHash, PosCompare> nodes;
map_size 是散列函数中使用的全局变量,可以让我得到一个完美的散列。
但是,我想将 map_size 作为参数传递给 PosHash,这样可以避免使用全局变量。我该怎么做?
PD: map_size 值在执行时确定
您可以将 map_size
作为 PosHash
结构中的数据成员。
struct PosHash{
public:
size_t operator()(array<int, 2> const& pos) const{
return pos[1] + pos[0]*map_size[1];
}
// Contructor that initializes the data member
PosHash(std::intializer_list<int> map_dim) : map_size(map_dim) {
// Other stuff
};
std::array<int, 2> map_size; // data member of the struct
};
然后你可以用需要的map_size
数组构造一个PosHash
对象。将此对象传递给您的 unordered_map
PosHash myPosHash({1, 2});
std::unordered_map<array<int, 2>, Node*, PosHash, PosCompare> nodes(\intial args\, myPosHash);
查看 std::unordered_map
here 的不同可用构造函数。您需要在 hasher 参数之前明确指定所有参数。这些将取决于您的需要。
我能想到的最简单的是
nodes(0, myPosHash); //initial #buckets, hasher object
这是一个完整的程序,展示了如何构造一个 PosHash
对象来存储特定值。请注意,您不需要自定义比较 - std::array
无论如何都以相同的方式进行比较。
#include <iostream>
#include <array>
#include <unordered_map>
using Pos = std::array<int, 2>;
struct PosHash {
PosHash(int m) : m_{m} { }
size_t operator()(const Pos& pos) const {
return pos[1] + pos[0] * m_;
}
int m_;
};
int main()
{
static constexpr size_t initial_bucket_count = 5;
// for illustrative purposes, will just map to ints
std::unordered_map<Pos, int, PosHash> m{initial_bucket_count, PosHash{4}};
m[Pos{2, 3}] = 23;
m[Pos{1, 1}] = 11;
m[Pos{3, 1}] = 11;
m[Pos{3, 2}] = 32;
for (const auto& x : m)
std::cout << x.first[0] << ',' << x.first[1] << '=' << x.second << '\n';
}
更一般地说,这是一个“弱”散列函数。它在生成散列值足以避免散列值 space 中的冲突方面可能是“完美的”,但这并不意味着如果将 space 折叠成散列值就不会发生冲突较少数量的桶。
我有以下结构:
array<int, 2> map_size;
struct Node{
int id;
array<int, 2> pos;
vector<Node*> nbs;
bool in_open;
bool in_closed;
};
每个节点都有一个在 map_size(全局变量)范围内的位置 (pos)。
我正在使用以下无序映射
struct PosHash{
public:
size_t operator()(array<int, 2> const& pos) const{
return pos[1] + pos[0]*map_size[1];
}
};
struct PosCompare{
bool operator()(const array<int, 2>& pos1, const array<int, 2>& pos2) const{
if (pos1[0] == pos2[0] and pos1[1] == pos2[1]){
return true;
}
else{
return false;
}
}
};
unordered_map<array<int, 2>, Node*, PosHash, PosCompare> nodes;
map_size 是散列函数中使用的全局变量,可以让我得到一个完美的散列。 但是,我想将 map_size 作为参数传递给 PosHash,这样可以避免使用全局变量。我该怎么做?
PD: map_size 值在执行时确定
您可以将 map_size
作为 PosHash
结构中的数据成员。
struct PosHash{
public:
size_t operator()(array<int, 2> const& pos) const{
return pos[1] + pos[0]*map_size[1];
}
// Contructor that initializes the data member
PosHash(std::intializer_list<int> map_dim) : map_size(map_dim) {
// Other stuff
};
std::array<int, 2> map_size; // data member of the struct
};
然后你可以用需要的map_size
数组构造一个PosHash
对象。将此对象传递给您的 unordered_map
PosHash myPosHash({1, 2});
std::unordered_map<array<int, 2>, Node*, PosHash, PosCompare> nodes(\intial args\, myPosHash);
查看 std::unordered_map
here 的不同可用构造函数。您需要在 hasher 参数之前明确指定所有参数。这些将取决于您的需要。
我能想到的最简单的是
nodes(0, myPosHash); //initial #buckets, hasher object
这是一个完整的程序,展示了如何构造一个 PosHash
对象来存储特定值。请注意,您不需要自定义比较 - std::array
无论如何都以相同的方式进行比较。
#include <iostream>
#include <array>
#include <unordered_map>
using Pos = std::array<int, 2>;
struct PosHash {
PosHash(int m) : m_{m} { }
size_t operator()(const Pos& pos) const {
return pos[1] + pos[0] * m_;
}
int m_;
};
int main()
{
static constexpr size_t initial_bucket_count = 5;
// for illustrative purposes, will just map to ints
std::unordered_map<Pos, int, PosHash> m{initial_bucket_count, PosHash{4}};
m[Pos{2, 3}] = 23;
m[Pos{1, 1}] = 11;
m[Pos{3, 1}] = 11;
m[Pos{3, 2}] = 32;
for (const auto& x : m)
std::cout << x.first[0] << ',' << x.first[1] << '=' << x.second << '\n';
}
更一般地说,这是一个“弱”散列函数。它在生成散列值足以避免散列值 space 中的冲突方面可能是“完美的”,但这并不意味着如果将 space 折叠成散列值就不会发生冲突较少数量的桶。