在双精度数组上使用unordered_map
问题描述:
我的主数据对象是一个长度为双精度的数组,它取决于我的类的特定实例。我想构造一个非常简单的哈希表来存储/检索这些对象,并且我们可以假设数字是以没有数字错误的方式生成的。在双精度数组上使用unordered_map
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;
}
上面明明只比较指针,使输出:
> ./tmp
x1: 1
x2: 0
当我真的想看到:
> ./tmp
x1: 1
x2: 1
这是很清楚如何创建自定义的散列和平等函数当数组的大小是固定在编译时间,但我不知道如何使自定义函数依赖于特定的我nstantiation ...我在下面创建了一个类,但我不确定它是否有用,或者它如何使用。
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 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;
当然是你的问题确保后备内存的生命周期是DoubleRegion生命周期的超集。
旧答:
如果你不知道,直到运行时有多大的键和值将是,使用一个std ::向量:
unordered_map<vector<double>, vector<double>> cache;
如果你知道编译时就可以有多大使用的std ::数组:
unordered_map<array<double, N>, array<double, N>> cache;
在这两种情况下,默认哈希函数将值作为你想要的工作,而你没有NE编辑定义一个自定义的。
我使用的是双数组,因为它是一个对这些对象进行大量操作的科学应用程序,double []具有比stl :: vector少得多的内存和计算开销。我可以通过在它们之间不断转换来实现散列,但这显然很昂贵。 – fairidox 2012-03-24 03:28:09
除了两个size_t计数(一个用于容量,一个用于大小),几乎没有开销 - 但为什么不能使用std :: array? N的可能值是什么?你能否让N成为你班级的模板参数?如果是这样,你可以将它传递给std :: array。 – 2012-03-24 03:33:27
N介于1到100之间,涉及的开销与操纵长双字符串有关。也就是说,我有一个长度为1000万的double []数组,我随机抽取大小在1到100之间的数组,我需要计算各种统计数据。我或许可以用来代替它,但是更容易传递一个&array [k],而不是构造一个迭代器,在所述迭代器上循环构造一个新的,然后传递该矢量 –
fairidox
2012-03-24 03:39:59