【问题标题】:Good Hashing Function良好的散列函数
【发布时间】:2021-02-15 17:56:12
【问题描述】:

我正在寻找一个哈希表来存储一些我需要快速访问的数据,而不是遍历链表,我在定义一个好的哈希函数时遇到了问题。

将 S 视为哈希表。

我用标签 (0,...,0) 初始化 S[10] 和 S[1w1] = (v11,v12)

然后我有两个循环,j=2 到 N,a=0 到 W。

N 和 W 可以是任意正整数。

在那里,我做 S[ja] = addSomeDifferentStuff(S[(j-1)a]),创建节点 S[j一个]。

我真的找不到不会产生冲突的哈希函数,我的一个朋友建议 hash = j + a * W。

有什么建议吗?

更新:

好的,所以我要澄清一下自己。这是基于将背包问题转换为最短路径问题的标记算法的双准则 0.1 背包问题的解决方案的实现。 W 是我的容量,n 是项目数。考虑 wj 项目 j 的权重。

在循环内部,我正在验证是否可以添加该项目,如果可以,那么我将 S[ja] = S[(j-1) awj] + values[j1,j2],否则我只是复制 S[ja ] = S[(j-1)a]。但是使用链接访问 S[(j-1)a] 或 S[(j-1)awj] 中的标签很昂贵列表,因为我需要遍历每个元素,直到找到它。这就是哈希表的目的。

【问题讨论】:

  • 不是我的头,但是有一些关于算法的书籍,它们对哈希函数有很好的起点。您应该只取其中一个并通过您的数据运行它以首先尝试。
  • 如果哈希空间小于输入空间,所有哈希函数都会产生冲突。
  • 对不起,但我不确定我是否遵循您的符号或算法描述。您是否在按位和运算符的正常 C 意义中使用 ^ 符号?如果S 是哈希表,那么我不明白你为什么要根据其他元素的值来计算它的元素。
  • 另外,我不遵循循环的目的。我想他们正在生成要存储在哈希表中的对象,但是这些对象是什么?值j^a?如果是这样,那么您确实意识到,您生成的不同值比 (j, a) 对少吗?
  • 更正:^ 作为按位异或。抱歉,来晚了。

标签: c hashtable hash-function


【解决方案1】:

N 和 W 可以是任意正整数。

这肯定会带来可计算性问题。您似乎在问如何为由分别从 0 ... N 和 0 ... W 范围内抽取的整数对组成的对象构造一个完美的散列函数。这样的函数必须计算 (N + 1) * (W + 1) 不同的值,并且 N 和 W 的界限会影响合适的数据类型和算法。

还要注意,将键视为整数 pairs 而不是整数 powers 可能最有用,因为 N 和 W 不需要得到在所涉及的权力太大而无法由您的实现提供的任何内置类型表示之前非常大。这些对将更容易在多个级别上使用。

我的一个朋友建议 hash = j + a * W。

我想你朋友的意思是 hash(j,a) = j + a * (N + 1)。假设它没有溢出,这将为从指定范围中抽取的每一对 (j, a) 产生不同的值。或者,您也可以使用 hash(j,a) = j * (W + 1) + a,但要遵守关于溢出的相同条件。如果您确实需要在您描述的整个域上使用完美的散列函数,那么我认为在性能方面没有太大的改进空间,除非可能用适当大的左移替换乘法。

然而,这些函数的值确实会以完全系统的方式随 a 和 j 变化,这对于此类函数的某些用途来说是不受欢迎的特征。找到一个不具有该属性的完美哈希函数是一个难题。人们通常会使用诸如 gperf 之类的程序来完成这样的任务,但这并不适合动态适应不同的 N 和 W 值。


请注意,虽然这回答了我认为您实际提出的问题,但我不确定这是否是您真正想要的。由于您似乎拒绝了我将S 描述为一个哈希表数组,而是回到它是一个单一的哈希表,我怀疑您所说的“哈希表”一词的意思与我的意思不同。不过,我认为这个问题是关于散列函数的,而您将该函数用于何种用途是一个单独的问题。

【讨论】:

    【解决方案2】:

    也许看看 https://github.com/Cyan4973/xxHash 的 xxHash 和它的竞争哈希函数列表。

    【讨论】:

    猜你喜欢
    • 2011-02-07
    • 2019-08-16
    • 2010-10-14
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 2013-06-09
    相关资源
    最近更新 更多