2d(3d)坐标的散列图(即双精度矢量)?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2d(3d)坐标的散列图(即双精度矢量)?相关的知识,希望对你有一定的参考价值。
我想知道是否有一个用于坐标的hash map
的一般全面解决方案(在2d或3d中,即双精度矢量)?
示例here演示了如何为pair<int,int>
创建自定义哈希映射,但是从pair<double,double>
(可以表示2d坐标)到size_t
的独特映射似乎并不容易。
我知道我可以通过提供比较器对象来使用有序地图,但是对于我的应用程序,没有必要对它们进行排序,并且哈希映射似乎更快。然而,因为我是所有这些hash
东西的新手,我有点迷失如何继续。
p / s / i使用c ++ 11。
为避免额外的依赖,您可以使用std::hash
。这是一个使用您发布的链接中的代码的示例,并更新为使用std::pair<double,double>
:
#include <unordered_map>
#include <cassert>
using namespace std;
class TPoint3D{
public:
TPoint3D(double x, double y, double z) : x(x), y(y), z(z){};
double x, y, z;
};
struct hashFunc{
size_t operator()(const TPoint3D &k) const{
size_t h1 = std::hash<double>()(k.x);
size_t h2 = std::hash<double>()(k.y);
size_t h3 = std::hash<double>()(k.z);
return (h1 ^ (h2 << 1)) ^ h3;
}
};
struct equalsFunc{
bool operator()( const TPoint3D& lhs, const TPoint3D& rhs ) const{
return (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.z == rhs.z);
}
};
typedef unordered_map<TPoint3D, int, hashFunc, equalsFunc> TPoint3DMap;
int main(){
TPoint3DMap myMap;
// test equalsFunc
myMap[TPoint3D(10.0, 20.0, 30.0)] = 100;
myMap[TPoint3D(10.0, 20.0, 30.0)] = 200;
assert(myMap[TPoint3D(10.0, 20.0, 30.0)] == 200);
// test if hashFunc handles well repeated values inside TPoint3D
myMap[TPoint3D(10.0, 10.0, 10.0)] = 1;
myMap[TPoint3D(10.0, 20.0, 10.0)] = 2;
myMap[TPoint3D(10.0, 10.0, 20.0)] = 3;
myMap[TPoint3D(20.0, 10.0, 10.0)] = 4;
assert(myMap[TPoint3D(10.0, 10.0, 10.0)] == 1);
assert(myMap[TPoint3D(10.0, 20.0, 10.0)] == 2);
assert(myMap[TPoint3D(10.0, 10.0, 20.0)] == 3);
assert(myMap[TPoint3D(20.0, 10.0, 10.0)] == 4);
return 0;
}
正如我之前所说,如果你想使用另一种结构,你必须调整pairHash
类和pairEquals
结构operator()
以分别适当地散列和比较新的键。
干杯
编辑:
- 修改代码以使用自定义TPPoint3D类和统一仿函数类定义(均使用struct)。
- 添加了简单的测试来验证哈希和等于仿函数。
我无法对Andre的回答发表评论,因为我还没有足够的声誉,但是任何尝试使用^(XOR)创建哈希函数的人都应该注意到XOR是关联的。换句话说a ^ (b ^ c) == (a ^ b) ^ c
。这意味着
(h1 ^ (h2 << 1)) ^ h3
这是安德烈答案的回归价值,与以下内容相同:
h1 ^ ((h2 << 1) ^ h3)
由于XOR(a ^ b == b ^ a
)的交换性质,它本身就相当于:
(h3 ^ (h2 << 1)) ^ h1
所有这一切意味着我所指的哈希方法,对于不同的a
,b
和c
,将为(a,b,c)
返回与(c,b,a)
相同的哈希值。换句话说,x和z坐标是顺序无关/不敏感的。
根据您使用此哈希方法的方式,这可能不是问题。但是,如果您正在散列的点与网格对齐,则会收到过多的散列冲突。
我将使用下面的一个替换Andre的答案中的return语句中的表达式。这应该是依赖于顺序/敏感的。
(h1 ^ (h2 << 1)) ^ (h3 << 2)
那么使用Boost的hash_combine
呢?
http://www.boost.org/doc/libs/1_53_0/doc/html/hash/combine.html
在3D情况下,假设您正在进行精确查找,std::unordered_map<std::tuple<double, double, double>, your_value_type>
应该可以正常工作。 std::tuple<...>
根据聚合类型的相等和散列函数为您定义相等和散列函数。
2D情况当然是相同的,但使用std::tuple<double, double>
。
编辑:对不起错误信息。实际上没有为std::tuple
定义的默认哈希。要使用这种方法,您必须定义一个hash_tuple
模板化仿函数类,然后在std::unordered_map
中使用它。其他答案显示了如何做到这一点。
以上是关于2d(3d)坐标的散列图(即双精度矢量)?的主要内容,如果未能解决你的问题,请参考以下文章