【问题标题】:Hashtables/Dictionaries that use floats/doubles使用浮点数/双精度的哈希表/字典
【发布时间】:2010-10-31 01:54:39
【问题描述】:

我在某处读到过其他类似哈希表、字典的数据结构,但它们不是使用整数,而是使用浮点数/双精度数等。

有人知道它们是什么吗?

【问题讨论】:

  • 在 .Net 中,此问题无效。如果您指定您的语言/开发工具,那么您可能会找到答案。
  • @David B:我认为这是一个理论上的算法问题:“除整数之外的东西可以用作哈希结构吗?”
  • 是的,这是一个通用的编程问题。

标签: data-structures dictionary hashtable


【解决方案1】:

一般来说,哈希算法只是一个从较大输入中产生较小输出的函数。良好的散列函数具有有趣的属性,例如输入的微小变化会导致输出的大变化,并保证它们为某些输入产生所有可能的输出值。

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

哈希函数几乎总是在整数算术中实现的至少部分原因是证明整数计算的各种属性比为浮点计算做同样的事情更容易。

很容易证明某些(素数之和)模(另一个素数)必须必然为某些输入产生所有可能的输出。对一堆浮点分数的计算做同样的事情会很麻烦。

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

【讨论】:

    【解决方案2】:

    你是说钥匙?这让我觉得很棘手。

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

    如果您希望计算一个浮点值并使用它在哈希表中查找某些内容,那么您的生活非常危险。浮点数没有无限的精度,以两种稍微不同的方式计算相同的东西可能会导致结果的微小差异。哈希键依赖于每次都得到完全相同的东西,所以你必须小心舍入,并且始终以完全相同的方式舍入。顺便说一句,这比听起来更棘手。

    那么,你会如何处理浮点哈希?

    【讨论】:

    • 谢谢,只是想知道他们是否有更大的哈希值集。虽然我记得如果我没记错的话,我看到了实际使用它们的数据结构。
    【解决方案3】:

    您的问题历史表明您使用 .Net,所以我会在这种情况下回答。

    如果您想要一个可识别类型的字典,以便您可以指定它应该对键或值使用浮点数或双精度数,请使用 System.Collections.Generic.Dictionary<T, U> http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

    如果您想要一个类型为盲的字典,以便您可以对键和值使用浮点数和双精度数,请使用 System.Collections.HashTable http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx

    【讨论】:

      【解决方案4】:

      如果您的意思是在哈希中使用浮点数/双精度数作为键,那很容易。例如,在 .NET 中,它只是使用 Dictionary<double,MyValueType>

      如果您正在谈论让哈希基于双精度而不是整数......

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

      但是,哈希实际上只是一个 BitArray,所以任何东西都可以工作。除了可能允许更大的散列值集(即:如果您为散列使用 8 字节或更大的类型)之外,将其设置为 int 或 long 确实没有太多优势。

      【讨论】:

      • 是的:从技术上讲,使用 long 作为哈希与使用 double(64 位数组)相同。如果您想要更长的时间,您可以使用 128 位类型,例如 GUID(相当于 .NET 中的十进制)。不过,整数类型的数学运算通常比浮点类型快。
      • @Joan Venge:是​​的。所有可散列类型都使用 Object.GetHashCode(),它返回一个 int。将 double 作为键就可以了 (302.298).GetHashCode()。这意味着您在 .NET 中有一个 32 位散列(使用标准类)。这与浮点数相同,但理论上,long 可以为您提供 2 倍的可能哈希值,而 GUID 可以提供 4 倍。
      • 没有。您需要为返回 GUID 的密钥编写自定义散列算法,以及在内部使用 GUID 而不是 int 的自定义 Dicionary/HashTable 类。所有 BCL 散列例程最终都在散列上使用 int ......不过,他们选择 int 是有充分理由的。 int 上的数学运算很快,并且由于它是 32 位的,因此您有 2^32 个可能的唯一哈希值。字典即使使用非唯一散列也能正常工作(只是不太好),因为散列计算通常会发生冲突。
      • 如果您的目标是获得更好的字典,那么您最好确保字典中键的 GetHashCode() 实现遵循规则并避免冲突尽可能。无论您使用多大的散列元素,散列只会与您计算散列 ID 的算法一样好。
      • 默认情况下,.NET 中的字典使用 int 作为它的哈希 [它是“int System.Object.GetHashCode()]。这意味着它有 32 个唯一位用于哈希,所以你得到 2^ 32 个值(这与浮点数相同,因为浮点数是 32 位)。如果您构建了一个使用长(或双)类型而不是 int 的自定义字典,您将拥有 64 个唯一位。使用 GUID(或十进制)它' d 是 128 个唯一位。它不是 2x,实际上是 2^32 vs. 2^64 vs. 2^128 - 我说错了 - 它是 2x 位,而不是 2x 哈希值。
      猜你喜欢
      • 1970-01-01
      • 2018-02-23
      • 2018-07-06
      • 1970-01-01
      • 1970-01-01
      • 2020-09-24
      • 1970-01-01
      • 2014-05-30
      • 1970-01-01
      相关资源
      最近更新 更多