这个Ruby代码是如何工作的? (哈希)(Learnrubythehardway)

时间:2015-05-26 07:54:26

标签: ruby hash

我知道我会看起来像一个完整的菜鸟,但有些东西我无法绕过我的脑袋。让我强调一点,我说谷歌这个东西,但我找不到我想要的东西。

我正在完成learnrubythehardway课程,对于ex39,这是我们定义的功能之一:

def Dict.hash_key(aDict, key)
    return key.hash % aDict.length
end

作者给出了这样的解释:

  

HASH_KEY       这个看似简单的函数是哈希工作方式的核心。它的作用是使用内置的Ruby散列函数来转换   字符串到一个数字。 Ruby将此函数用于自己的哈希数据   结构,我只是重复使用它。你应该启动一个Ruby控制台   看看它是如何工作的。一旦我有一个密钥的数字,我然后使用   % (modulus)运算符和aDict.length获取一个存储桶   钥匙可以去。如您所知,% (modulus)运算符将分开   任何数字,给我剩下的。我也可以用它作为一种方式   将巨号限制为一组固定的其他数字。如果你   不要得到这个然后用Ruby来探索它

我喜欢这个课程,但上一段没有帮助。 好的,你调用函数传递两个参数(aDict是一个数组)并返回一些东西。 (我的问题并不完全相互独立。)

  1. 它是做什么的,怎么做? (好吧,它返回一个存储桶索引,但我们如何“到达那里”?)
  2. key.hash做什么/它是什么?
  3. 使用%如何帮助我获得我需要的东西? (“key.hash”{/ 1>对aDict.length进行“修改”有什么用?
  4. “使用Ruby来探索它。” - 好的,但我的问题2。有点已经暗示我不知道该怎么做。
  5. 提前致谢。

2 个答案:

答案 0 :(得分:3)

key.hash正在调用Object#hash,不要与Hash混淆。

Object#hash将字符串一致地转换为数字(相同的字符串将始终生成相同的数字,在同一个运行的Ruby实例中)。

pry(main)> "abc".hash
=> -1672853150

所以现在我们有一个数字,但它对于我们的Dict结构中的桶数太大了,默认为256个桶。所以我们将它模数得到我们的铲斗范围内的数字。

pry(main)> "abc".hash % 256
=> 98

这实质上允许我们将Dict["abc"]翻译成aDict[98]

答案 1 :(得分:1)

RE:特别是这个例子

我将以一种我希望更有意义的方式改变事物的顺序:

#2。您可以将哈希视为某种“指纹”。 .hash方法将为任何给定输入创建(通常)唯一输出。

#3。在这种情况下,我们知道散列是一个数字,所以我们将生成的数字的模数除以后备数组的长度,以便找到一个(希望是空的)索引,它位于我们存储的范围内。

#1。这就是如何。散列算法将为任何给定输入返回相同的输出。模数采用此输出并将其转换为我们可以在数组中实际使用的东西,以便可靠地找到它。

#4。在某事上致电hash。在字符串上调用它,然后按数组的长度对其进行模数化。再试一次另一个字符串。再次这样做,并使用您的结果为该数组分配一些东西。再做一遍,看看hash和modulo会再次找到该值。

进一步说明:

模数函数本身并不是为键选择唯一索引的好方法。这个例子是第一步,但特别是在一个小数组中,不同键的哈希值仍然存在相对较大的机会成为相同的数字。这被称为碰撞,处理这些似乎超出了这个问题的范围。