【问题标题】:Hash functions and how they work哈希函数及其工作原理
【发布时间】:2011-09-17 03:27:10
【问题描述】:

所以我有两种不同的字段类型,一个长度为 n 的 char* 和一个 int。我想使用两者作为键来生成哈希值。我添加了 int 变量的最后 16 位,我们将其称为 sum 整数 x,然后我使用 collat​​e: hash 为 char* 生成一个哈希值,我们将其称为整数 y。然后我将 x+y 加在一起,然后将哈希与总和一起使用以生成哈希值。假设我想将哈希值限制在 [1,4] 的范围内。我可以只用 hashvalue%4 来得到我想要的吗?另外,如果有更好的方法从两个键生成哈希值,请告诉我。

【问题讨论】:

    标签: c++ hash


    【解决方案1】:

    对于范围 [1,4],您必须将 1 添加到 hashvalue%4。但是,4 的散列是一个非常小的散列。这会给你带来很多冲突,限制哈希的有效性(也就是说,许多不同的字段值会给你相同的哈希值。)

    我建议您向散列添加更多大小(位),也许是 64K(16 位散列)。这会给你更少的碰撞。另外,为什么不使用已经实现哈希表的std::unordered_map

    最后,根据散列函数,它取决于每个字段的含义。例如,如果在您的实现中,只计算整数的低 16 位,那么哈希应该仅基于这些位。有用于字符串和整数的通用散列函数,因此您可以使用它们中的任何一个。最后,为了组合两个字段的哈希值,对它们求和(或异或)是一种常见的方法。只需确保生成的哈希值尽可能均匀地分布在该范围内即可。

    【讨论】:

      【解决方案2】:

      所以,你用很多词描述的都是这样写的:

      struct noname {
        int ifield;
        char[N] cfield;
      };
      
      int hash(const noname &n) {
        int x = n.ifield;
        int y = ???(n.cfield);
        return x + y;
        // return (x + y) & 3;
      }
      

      这个hash函数好不好就看数据了。例如,如果ifield 始终是 4 的倍数,那么它显然很糟糕。如果字段的值大致均匀分布,则一切正常。

      好吧,除了您要求将哈希范围限制为[1;4]。首先,[0;3] 更容易计算,其次,如果你只有两三个不同的东西会生成哈希码,那么这么小的范围是合适的。该范围应至少是预期不同元素数量的两倍。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-07
        • 2021-07-07
        • 2012-02-28
        • 2019-08-26
        • 2012-03-23
        • 2013-04-22
        相关资源
        最近更新 更多