【问题标题】:Efficiently calculating containers hash codes高效计算容器哈希码
【发布时间】:2017-02-20 05:02:32
【问题描述】:

我所知道的用于计算容器哈希码的算法通过递归组合其中所有元素的哈希来工作。哈希的组合方式与我的问题无关。但是因为算法是递归的,所以计算会变得非常昂贵。 O(n),其中 n 是可到达的元素总数。

我的问题是是否有更有效的方法来做到这一点?例如,如果您有一个包含 100k 个元素的数组,您可以通过组合仅包含 100 个元素的哈希来计算哈希。这将使计算速度提高 1000 倍,同时仍然是一个很好的哈希函数,不是吗?

您选择的 100 个元素可以是第 100 个或每 1000 个(在上面的示例中)或使用其他确定性公式选择。

所以为了回答我的问题,你能否或者告诉我为什么我的想法行不通或者告诉我我的想法已经在哪里进行了调查。就像我提议的那样,是否有任何编程语言实现了“sub O(n) 序列哈希”?

【问题讨论】:

  • 哈希是为了什么目的?如果您使用 XOR 之类的通勤组合运算符,那么您只需在操作容器时更新哈希即可。

标签: algorithm hash containers time-complexity hashcode


【解决方案1】:

一般来说,设计一个合适的哈希函数需要权衡计算时间和质量,对于非常大的对象尤其如此。

仅对大对象的固定大小子集进行散列是一种有效的策略(例如,Lua 使用此策略对大字符串进行散列),但如果散列对象几乎没有差异并且碰巧发生这种情况,它显然会导致问题差异不在散列子集中。这开启了拒绝服务攻击(或意外触发相同问题的输入)的可能性,因此如果您正在散列不受控制的输入,通常不是一个好主意。 (如果您将哈希用作加密练习的一部分,那么省略部分对象会使伪造变得微不足道,因此在这种情况下,这是一个非常糟糕的主意。)

假设您将哈希用作数据库索引策略(即哈希表)的一部分,请记住,最后您需要将正在查找的值与表中的每个潜在匹配项进行比较;这些比较必然是 O(n)(除非您相信几乎所有查找都会失败)。每个误报都需要进行额外的比较,因此质量与计算时间的权衡可能会被证明是一种错误的经济。

但是,最终,并没有明确的答案;您必须根据您拥有的确切用例做出决定,包括考虑您使用哈希的目的、数据的分布是(或可能是)等等。

【讨论】:

  • 我不明白您在质量与计算时间之间的权衡。看来我的方法不需要额外的比较,而是会增加哈希表中冲突的风险(取决于数据)?感谢Lua参考,我会看看它。但肯定有更多的人考虑过这种权衡?谷歌搜索时我什么也没想到。
  • @björn:如果有更多的碰撞,就会有更多的比较,因为你必须验证每一个命中。恕我直言,这不是一个常见的选择,因为(a)散列非常大的对象很少见,并且(b)无法避免比较的成本。 (对于大对象,计算hash会有效地预加载缓存,因此后续比较更便宜。)当然是YMMV。
猜你喜欢
  • 2017-02-04
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 2016-06-23
  • 2022-07-06
  • 1970-01-01
  • 2015-05-28
  • 1970-01-01
相关资源
最近更新 更多