Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 使用一对值作为键_Ruby_Algorithm_Hash_Time Complexity - Fatal编程技术网

Ruby 使用一对值作为键

Ruby 使用一对值作为键,ruby,algorithm,hash,time-complexity,Ruby,Algorithm,Hash,Time Complexity,我经常需要散列一对值。通常,我只是生成一个介于num1和num2之间的范围,并将其作为一个键进行散列,但这相当慢,因为这两个数字之间的距离可能相当大 如何将一对值散列到一个表中?例如,假设我遍历一个数组,并希望将每一个可能的值对散列到一个散列表中,其中键是NUM对,值是它们的和。做这件事的有效方法是什么?我还考虑过将数组散列为键,但这不起作用 还有,如何将其扩展到3、4或5个数字 编辑: 我指的是哈希表中O(1)查找的哈希。如果您使用的是范围或数组,那么您也可以调用它并使用它 (num1..nu

我经常需要散列一对值。通常,我只是生成一个介于num1和num2之间的范围,并将其作为一个键进行散列,但这相当慢,因为这两个数字之间的距离可能相当大

如何将一对值散列到一个表中?例如,假设我遍历一个数组,并希望将每一个可能的值对散列到一个散列表中,其中键是NUM对,值是它们的和。做这件事的有效方法是什么?我还考虑过将数组散列为键,但这不起作用

还有,如何将其扩展到3、4或5个数字

编辑:
我指的是哈希表中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 Ruby
hash
函数旨在最小化冲突,而不是避免冲突。这是任何“哈希表”的主干,就像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}