很多時候我需要散列一對值。通常,我只是在num1和num2之間生成一個範圍,並將其作爲一個鍵進行散列,但這很慢,因爲這兩個數字之間的距離可能非常大。使用一對值作爲密鑰
如何才能將一對值散列到表中?例如,假設我正在遍歷一個數組,並且希望將每個可能的一對值散列到散列表中,其中鍵是num對,並且值是它們的總和。什麼是有效的方法來做到這一點?我也想過把一個數組散列爲關鍵字,但這不起作用。
另外,如何將其擴展到3,4或5個數字?
編輯: 我指的散列表中的O(1)查找散列。
很多時候我需要散列一對值。通常,我只是在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(其他)→真或假
返回是否真實的自我等是同一個對象,或具有相同內容兩個數組(?根據Object#eql?)。
散列→整數
計算此數組的散列碼。
與相同內容的兩個數組將具有相同的散列碼(並且將使用eql?進行比較)。
強調我的。
這似乎與我的答案是一樣的:)更多的解釋如何'哈希'工程 – Dbz
如果您使用的是range
或array
,那麼您也可以撥打hash
並使用它。
(num1..num2).hash
[num1, num2].hash
將返回,你可以作爲哈希使用的密鑰。我不知道這是否有效。它確實在range documentation和array documentation
上顯示源代碼另一種方法是將數字轉換爲字符串。如果您擔心散列衝突,這是更好的解決方案。
'num1:num2'
而且我會解決你的問題紅寶石式的方法是:
number_array.combination(2).each { |arr| my_hash[arr.hash] = arr }
number_array.combination(2).each { |arr| my_hash[arr.join(":")] = arr }
哈希表,其中鍵是一對NUMS的和值是它們的總和:
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個數字,請使用combination(3) #or 4 or 5
。
你可以散列一個字符串''num1:num2''嗎? – Dbz
@Dbz我不確定這是否有效 - 在將它們散列之前將數字轉換爲字符串。但是,如果這是最好的方式,那麼我肯定這是正確的。 – Sunny
是否都是正值?他們是整數嗎? – eiko