【问题标题】:What hash function used in dictionary (hash_table)?字典(hash_table)中使用了什么哈希函数?
【发布时间】:2012-09-25 19:43:43
【问题描述】:

我正在编写语言解释器。 有问题:我想创建类型字典,您可以在其中按索引放置任何类型的值,任何类型的值(简单类型的简单 [int,float,string] 或复杂 [list,array,dictionary] 或复杂的简单类型...)。这与 python-lang 中的相同。 我应该使用什么哈希函数算法?

对于字符串,有许多哈希示例 - 最简单的:所有字符的总和乘以 31,然后除以 HASH_SIZE,这个简单的数字。

但是对于不同的类型,我认为,它必须是更复杂的算法。 我找到了 SHA256,但不知道如何使用“unsigned char [32]”结果类型在哈希表中进行寻址 - 它比计算机中的 RAM 多得多。 谢谢。

【问题讨论】:

  • SHA 系列哈希是加密哈希。它们不适合哈希表实现。
  • 实际上,在 Python 中,您不能将列表、数组或字典存储在哈希表中——您可以存储复杂的对象,但它们必须是不可变的。

标签: c++ hash dictionary hashtable hash-function


【解决方案1】:

C++11 中有哈希表,最新的 C++ 标准 - std::unordered_map, std::unordered_set。

编辑:

由于每种类型都有不同的分布,通常每种类型都有自己的哈希函数。这就是在 Java(从 Object 继承的 .hashCode() 方法)、C#、C++11 和许多其他实现中的实现方式。

EDIT2:

典型的哈希函数做两件事:

1.) 以自然数创建对象表示。 (这就是 Java 中的 .hashCode() 所做的) 例如 - 字符串“CAT”可以转换为:

67 * 256^2 + 65 * 256^1 + 84 = 4407636

2.) 将此数字映射到数组中的位置。 一种方法是:

integer_part(fractional_part(k*4407636)*m)

其中 k 是一个常数(Donald Knuth 在他的《编程艺术》一书中建议使用 (sqrt(5)+1)/2),m 是哈希表的大小,fractional_part 和 integer_part (显然)计算小数部分和整数部分实数。

在您的哈希表实现中,您需要处理冲突,尤其是当可能的键比哈希表的大小多得多时。

EDIT3:

我阅读了有关该主题的更多内容,看起来像 67 * 256^2 + 65 * 256^1 + 84 = 4407636 做hash_code真的很糟糕。这是因为,“somethingAAAAAAABC”和“AAAAAABC”给出完全相同的哈希码。

【讨论】:

  • 树用于 STL。但我想自己实现字典。你的意思是,我应该使用树而不是 hash_table?
  • 不不不,STL 中有树,但最新版本的 C++ 标准添加了哈希表 - 注意有 map(树)和 unordered_maps(哈希表)。
  • 我没有对象/类——只有简单的类型和容器。我需要为容器发明精确的 hash_function。所以从编辑我可以理解,我在 unordered_map 中找不到确切的哈希算法,因为谁写了类,写了它。或者他们有一个用于向量、列表、...?
  • 是的。大多数哈希表实现将创建哈希函数委托给其他人 - 在 Java 的示例中,类作者。由于我错误地认为这个问题是关于“gimme teh hash function”的,我很快就会再次编辑我的答案。
【解决方案2】:

嗯,一种常见的做法是将散列函数定义为属于该类型的方法。 这样您就可以通过一个通用 API 为不同类型调用不同的算法。

当然,这需要您为要在解释器中使用的每个 baisc“c 类型”定义包装类。

【讨论】:

  • 好的,可以编码了。但是,当我将它放入字典时,我必须将什么 hash_function 用于字典类型 - 它是其中元素的哈希值之和?我应该采取什么 sum_function?
  • 将字典放在另一个字典中是不安全的。由于字典可能会更改其内容(并因此刷新其哈希值),因此查找将中断。
  • 听起来很疯狂。字典的哈希函数执行,即索引(我不知道什么时候需要,但我认为这样做)。您不能更改索引,只能通过找到的索引更改值。 a = dict[{1,"2"}] + 7;
猜你喜欢
  • 1970-01-01
  • 2015-11-14
  • 1970-01-01
  • 2015-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 2014-01-30
相关资源
最近更新 更多