Ruby 使用一对值作为键
我经常需要散列一对值。通常,我只是生成一个介于num1和num2之间的范围,并将其作为一个键进行散列,但这相当慢,因为这两个数字之间的距离可能相当大 如何将一对值散列到一个表中?例如,假设我遍历一个数组,并希望将每一个可能的值对散列到一个散列表中,其中键是NUM对,值是它们的和。做这件事的有效方法是什么?我还考虑过将数组散列为键,但这不起作用 还有,如何将其扩展到3、4或5个数字 编辑:Ruby 使用一对值作为键,ruby,algorithm,hash,time-complexity,Ruby,Algorithm,Hash,Time Complexity,我经常需要散列一对值。通常,我只是生成一个介于num1和num2之间的范围,并将其作为一个键进行散列,但这相当慢,因为这两个数字之间的距离可能相当大 如何将一对值散列到一个表中?例如,假设我遍历一个数组,并希望将每一个可能的值对散列到一个散列表中,其中键是NUM对,值是它们的和。做这件事的有效方法是什么?我还考虑过将数组散列为键,但这不起作用 还有,如何将其扩展到3、4或5个数字 编辑: 我指的是哈希表中O(1)查找的哈希。如果您使用的是范围或数组,那么您也可以调用它并使用它 (num1..nu
我指的是哈希表中O(1)查找的哈希。如果您使用的是
范围或数组,那么您也可以调用它并使用它
(num1..num2).hash
[num1,num2].散列
这将返回一个可以用作散列的密钥。我不知道这是否有效。它确实在和上显示了源代码
另一种方法是将数字转换成字符串。如果您担心哈希冲突,这是更好的解决方案
'num1:num2'
我可以用ruby风格的方法来解决你的问题:
number_数组.组合(2).每个{| arr | my_hash[arr.hash]=arr}
number_array.composition(2)。每个{arr | my_hash[arr.join(“:”)=arr}
就这样做吧。
您可以简单地对数组进行散列
验证
让我做一个小实验:
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
正如您所看到的,您不仅可以使用数组作为键,还可以将它们识别为“相同”(而不是它也可能是的一些奇怪的对象标识)
警告
显然,这只在一定程度上有效。数组的内容必须递归地定义好散列。也就是说,您可以在其中使用正常的东西,比如字符串、数字、其他数组,甚至nil
参考文献
发件人:
当两个对象的哈希值相同且两个对象是eql时,它们引用相同的哈希键?相互之间
发件人:
eql?(其他)→ 真假
如果self和other是同一个对象,或者都是具有相同内容的数组(根据object#eql?),则返回true
散列→ 整数
计算此数组的哈希代码
具有相同内容的两个数组将具有相同的哈希代码(并将使用eql进行比较?)
Emphasis mine.一个哈希表,其中键是一对NUM,值是它们的和:
h = {}
[1,4,6,8].combination(2){|ar| h[ar] = ar.sum}
p h #=>{[1, 4]=>5, [1, 6]=>7, [1, 8]=>9, [4, 6]=>10, [4, 8]=>12, [6, 8]=>14}
请注意,使用数组作为哈希键根本没有问题。若要将其扩展到3、4或5个数字,请使用组合(3)#或4或5
能否对字符串进行散列'num1:num2'
?@Dbz我也不确定这是否有效--在散列之前将数字转换为字符串。但如果这是最好的方法,那么我肯定会将其标记为正确的。您是指SHA256中的散列还是指“在散列中用作密钥”中的散列?你想解决的更大的问题是什么?你能在这里举个例子吗?这些数字是1..10
还是290..3345362
?这种哈希表数据结构的用途是什么?“施工后你如何使用它?”Sunny我们回答了你的问题吗?如果不是,您还想知道什么?哈希返回的值不能保证唯一以避免冲突。这就是散列函数的定义:它将一个大的(r)(可能无限)输入空间映射到一个小的(er)有限输出空间。鸽子洞原理保证一定会有碰撞,这是真的。对数组对进行哈希运算时,哈希冲突是一件大事吗?我不知道用例,但我怀疑它;然而,这是值得一提的。@Dbz我只是想对比一下散列
,它在较新版本的Ruby中似乎会产生64位值,而像SHA512或UUID这样的东西则极不可能发生冲突。正如Jörg所提到的,由于鸽子洞原理,另外由于64位值很可能会发生冲突。@dbz Rubyhash
函数旨在最小化冲突,而不是避免冲突。这是任何“哈希表”的主干,就像Ruby中的Set和hash一样。在发生冲突的情况下,哈希表函数只会进行额外的比较,这一切都会成功,但这只是因为保留了原始值。这似乎与我的答案相同:)并对哈希
的工作原理进行了更多解释
h = {}
[1,4,6,8].combination(2){|ar| h[ar] = ar.sum}
p h #=>{[1, 4]=>5, [1, 6]=>7, [1, 8]=>9, [4, 6]=>10, [4, 8]=>12, [6, 8]=>14}