Data structures 使用浮点/双精度的哈希表/字典

Data structures 使用浮点/双精度的哈希表/字典,data-structures,dictionary,hashtable,Data Structures,Dictionary,Hashtable,我在某个地方读到过类似于哈希表、字典的其他数据结构,但它们没有使用int,而是使用float/double等 有人知道它们是什么吗?如果你的意思是在散列中使用浮点/双精度键,那很简单。例如,在.NET中,它只是使用字典 如果你说的是让散列值基于双精度而不是整数 从技术上讲,您可以使用任何元素作为内部哈希。通常,这是使用int或long来完成的,因为它们很快,并且散列算法很容易计算 然而,散列实际上只是一个位数组,所以任何东西都可以工作。除了允许使用更大的哈希值集(即,如果您的哈希值为8字节或更大

我在某个地方读到过类似于哈希表、字典的其他数据结构,但它们没有使用int,而是使用float/double等


有人知道它们是什么吗?

如果你的意思是在散列中使用浮点/双精度键,那很简单。例如,在.NET中,它只是使用
字典

如果你说的是让散列值基于双精度而不是整数

从技术上讲,您可以使用任何元素作为内部哈希。通常,这是使用int或long来完成的,因为它们很快,并且散列算法很容易计算


然而,散列实际上只是一个位数组,所以任何东西都可以工作。除了允许使用更大的哈希值集(即,如果您的哈希值为8字节或更大的类型)之外,将其设置为int或long并没有什么好处。

您的问题历史记录显示您使用.Net,因此我将在该上下文中回答

如果您想要一个类型识别的字典,以便您可以指定它应该对键或值使用浮点或双精度,请使用
System.Collections.Generic.Dictionary


如果您想要一个类型为盲的字典,例如可以对键和值使用浮点和双精度,请使用
System.Collections.HashTable

您的意思是作为键?我觉得这很棘手

如果您将它们用作任意键,它们并不比整数更好

如果您希望计算一个浮点值并使用它在哈希表中查找某些内容,那么您的生活非常危险。浮点数的精度不是无限的,用两种稍有不同的方法计算同一事物,可能会导致结果的微小差异。哈希键依赖于每次获得完全相同的内容,因此您必须小心地进行取整,并始终以完全相同的方式进行取整。顺便说一句,这比听起来要复杂


那么,如何处理浮点散列呢?

一般来说,散列算法只是一个从较大的输入中产生较小输出的函数。好的散列函数有一些有趣的特性,比如输入的小变化导致输出的大变化,以及保证它们为某些输入生成所有可能的输出值

编写一个输出浮点值而不是整数值的简单多项式类型散列函数并不困难,但如果不深入了解所使用的特定浮点表示形式的细节,就很难确保生成的散列函数具有所需的属性

哈希函数几乎总是在整数运算中实现的原因,至少有一部分是因为证明整数计算的各种属性比证明浮点计算的各种属性更容易

很容易证明某些(素数因子之和)模(另一个素数)必然会为某些输入产生所有可能的输出。对一组浮点分数进行同样的计算将是一种阻力


此外,在不损坏的情况下存储和传输浮点值是相对困难的,这是不值得的。

在.Net中,这个问题是无效的。如果你指定了你的语言/devtools,那么可能会有一个答案。@David B:我认为这是一个理论算法问题:“除了整数以外的东西可以用作散列结构吗?”是的,这是一个一般的编程问题。是的:从技术上讲,使用long as散列与使用double(64位数组)是一样的。如果需要更长的时间,可以使用128位类型,例如GUID(相当于.NET中的十进制)。整数类型的数学运算速度通常比浮点类型快。@Joan Venge:是的。所有可散列类型都使用Object.GetHashCode(),它返回一个int。将double作为键(302.298)。GetHashCode()。这意味着您在.NET中有一个32位的哈希(使用标准类)。这与float相同,但从理论上讲,long可能会使哈希值增加2倍,GUID可能会增加4倍。否。您需要为您的密钥编写一个自定义哈希算法,该算法返回一个GUID,以及一个自定义Dicionary/HashTable类,该类在内部使用GUID而不是int。所有BCL哈希例程最终在哈希上使用int。。。不过,他们选择int是有充分理由的。int上的数学运算速度很快,因为它是32位的,所以有2^32个可能的唯一哈希值。即使使用非唯一散列,字典也能正常工作(只是不太好),因为散列计算通常会发生冲突。不过,如果您的目标是获得更好的字典,那么最好确保您的GetHashCode()字典中键的实现遵循规则并尽可能避免冲突。无论您使用的哈希元素有多大,哈希都将与您计算哈希ID的算法一样好。默认情况下,.NET中的字典使用int作为其哈希[它是“int System.Object.GetHashCode()”。这意味着它有32个唯一的哈希位,因此您得到2^32个值(这与float相同,因为float是32位的)。如果您构建了一个使用long(或double)类型而不是int的自定义字典,那么您将拥有64个唯一位。使用GUID(或decimal)它将是128个唯一位。它不是2x,它实际上是2^32对2^64对2^128-我说错了-它是2倍的位,而不是2倍的散列值。谢谢,我只是想知道它们是否有更大的散列值集。虽然我记得看到过数据结构,如果我没有错的话,实际上使用它们。