我经常需要散列一对值通常,我只是生成num1和num2之间的一个范围,并将其作为一个键进行散列,但这相当慢,因为这两个数字之间的距离可能相当大。
如何将一对值散列到表中?例如,假设我正在遍历一个数组,并希望将每一个可能的值对散列到一个散列表中,其中键是一对num,值是它们的和做这件事的有效方法是什么?我还考虑过将数组散列作为键,但这不起作用。
另外,如何将其扩展到3、4或5个数字?
编辑:
我指的是哈希表中O(1)查找的哈希。
最佳答案
想做就做。
你可以简单地对数组进行哈希运算…
验证
让我展示一个小实验:
array = [ [1,2], [3,4], ["a", "b"], ["c", 5] ]
hash = {}
array.each do |e|
e2 = e.clone
e << "dummy"
e2 << "dummy"
hash[e] = (hash[e] || 0) + 1
hash[e2] = (hash[e2] || 0) + 1
puts "e == e2: #{(e==e2).inspect}, e.id = #{e.object_id}, e.hash = #{e.hash}, e2.id = #{e2.object_id}, e2.hash = #{e2.hash}"
end
puts hash.inspect
如您所见,我提取了几个数组,克隆它们,分别对它们进行修改;在此之后,我们确信
e
和e2
是不同的数组(即不同的对象id);但是它们包含相同的元素之后,这两个不同的数组被用作散列键;由于它们具有相同的内容,所以被散列在一起。e == e2: true, e.id = 19797864, e.hash = -769884714, e2.id = 19797756, e2.hash = -769884714
e == e2: true, e.id = 19797852, e.hash = -642596098, e2.id = 19797588, e2.hash = -642596098
e == e2: true, e.id = 19797816, e.hash = 104945655, e2.id = 19797468, e2.hash = 104945655
e == e2: true, e.id = 19797792, e.hash = -804444135, e2.id = 19797348, e2.hash = -804444135
{[1, 2, "dummy"]=>2, [3, 4, "dummy"]=>2, ["a", "b", "dummy"]=>2, ["c", 5, "dummy"]=>2}
如您所见,您不仅可以使用数组作为键,还可以将它们识别为“相同的”(而不是它也可能是的一些奇怪的对象标识)。
警告
显然这只起到了一定的作用。数组的内容必须递归地定义好与哈希有关的内容也就是说,你可以使用一些理智的东西,比如字符串、数字、其他数组,甚至
nil
。参考
从http://ruby-doc.org/core-2.4.0/Hash.html:
当两个对象的散列值相同且两个对象是eql时,它们引用同一个散列键彼此之间。
从http://ruby-doc.org/core-2.4.0/Array.html#method-i-eql-3F:
eql?(其他)→正确或错误
如果self和other是同一个对象,或者两个数组的内容相同(根据object-eql?)是的。
哈希→整数
计算此数组的哈希代码。
具有相同内容的两个数组将具有相同的哈希代码(并将使用eql进行比较?)是的。
强调我的。