在双精度数组上使用unordered_map [英] Using unordered_map on array of doubles

查看:125
本文介绍了在双精度数组上使用unordered_map的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的主数据对象是一个长度的二进制数组,取决于我的类的具体实例。我想构造一个非常简单的哈希表来存储/检索这些对象,我们可以假设数字是以没有数字错误的方式生成的。

My main data object is a array of doubles of a length that depends on a specific instantiation of my class. I would like to construct a very simple hash table to store/retrieve these objects, and we can assume that the numbers are generated in a way that is free of numerical error.

int main() {
  std::tr1::unordered_map<double*, double*> cache;

  double x1[] = { 1.0, 3.14 };
  double x2[] = { 1.0, 3.14 };

  cache[x1] = x1;

  std::cout << "x1: " << cache.count(x1) << std::endl;
  std::cout << "x2: " << cache.count(x2) << std::endl;

  return 0;
}

上面显然只比较了指针,给出了输出:

The above obviously only compares the pointers, giving the output:

> ./tmp
x1: 1
x2: 0

当我真的想要看到:

> ./tmp
x1: 1
x2: 1

很明显当编译时固定数组的大小时,创建自定义散列和等式函数,但是我不知道如何使定制函数依赖于一个特定的实例化...我在下面创建了一个类,但是我不知道它是有用的,还是可以使用的。

It's pretty clear how to create custom hashing and equality functions when the size of the arrays are fixed at compile time but I do not know how to make custom functions that depend on a specific instantiation... I created a class below, but I'm not sure if it's useful, or how it could be used.

class Hash_double_vec {

public:
  int dim;
  Hash_double_vec(int d) { dim = d; }

  size_t operator()(const double *x) const{
    std::tr1::hash<double> hash_fn;
    size_t r = hash_fn(x[0]);
    for(int i=1;i<dim;i++) r ^= hash_fn(x[i]);
    return r;
  }

  bool operator()(const double *x, const double *y) const{
    for(int i=1;i<dim;i++) if (fabs(x[i]-y[i]) > 1e-10) return false;
    return true;
  }
};


推荐答案

一种方法是创建struct来保存指针到双打的顺序:

One way would be to create struct to hold the pointer to the sequence of doubles:

struct DoubleRegion
{
    double* p;
    size_t size;
};

bool operator==(DoubleRegion a, DoubleRegion b)
{
    return a.size == b.size && memcmp(a.p, b.p, a.size) == 0;
}

size_t hash(DoubleRegion dr) 
{
    size_t h = 0;
    for (double* p = dr.p; p != dr.p + dr.size; ++p)
        h ^= hash(*p);
    return h;
}

然后使用它:

unordered_map<DoubleRegion, DoubleRegion> cache;

当然这是您的问题,以确保后备内存的生命周期是生命周期的超集的双重地区。

Of course it is your problem to make sure the lifetime of the backing memory is a superset of the lifetime of the DoubleRegion.

旧答案

如果你不知道直到运行时,键和值将会有多大,请使用std :: vector:

If you don't know until runtime how big the key and value is going to be, use a std::vector:

unordered_map<vector<double>, vector<double>> cache;

如果您在编译时知道可以使用std ::数组大小:

If you know at compile-time how big you can use an std::array:

unordered_map<array<double, N>, array<double, N>> cache;

在这两种情况下,默认散列函数将根据需要按值工作,您不需要定义一个定制的。

In both cases the default hashing function will work by value as you want, and you do not need to define a custom one.

这篇关于在双精度数组上使用unordered_map的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆