2014-06-10 64 views
0

紅寶石非貪婪memoized哈希,硬幣找零的解決方案:硬幣更改遞歸散列(解釋)?

def coin_change amt, denom_arr 
    coins = Hash.new do |coin, key| 
    coin[key] = if key < denom_arr.min 
     [] 
    elsif denom_arr.include? key 
     [key] 
    else 
     denom_arr. 
     reject { |coin| coin > key }. 
     reduce([]) { |memo, denom| memo.any? {|coin| coin%denom==0 } ? memo : memo+[denom] }. 
     map {|denom| [denom] + coin[key-denom]}. 
     min { |a, b| a.size <=> b.size } 
    end 
    end 
    coins[amt] 
end 

p coin_change 6, [4,3,1] 
#=> [3,3] 

究竟被送入這條線? .reduce([]) { |memo, denom| memo.any? {|coin| coin%denom==0 } ? memo : memo+[denom] }(據我可以告訴它是一個硬幣<鍵陣列)有人可以告訴我一個如何這個細分的例子?

另外我得到,如果{|coin| coin%denom==0 }是真的返回memo但什麼是memo+[denom]究竟是什麼?

我明白.any?方法返回真如果塊返回非假或零的值。

我以爲memo是一個數組,但我打電話給它的類,它返回Class

[4,3,8,7].inject([]) { |memo, denom| memo.class } 
#=> Class 

總之有人可以在步驟與示例輸出解釋:

  • 這條線:.reduce([]) { |memo, denom| memo.any? {|coin| coin%denom==0 } ? memo : memo+[denom] }
  • 你能給的遞歸碼哈希鍵/值對每個內容示例迭代? **

** ie。 denom_arr = 4,3,1amt = 6第一次傳遞哈希的樣子是什麼樣的?二次傳遞哈希是什麼樣子?在第三遍等等,直到完成...什麼是散列樣子?

+0

hmm .. http://codereview.stackexchange.com/也許? – quetzalcoatl

+1

@quetzalcoatl我認爲它的套件更好,因爲codereview給我建議我理解代碼,並期待可能優化它,而SO更多是*幫助我理解這種類型的論壇。 – fyz

回答

1
.reduce([]) { |memo, denom| memo.any? {|coin| coin%denom==0 } ? memo : memo+[denom] } 

denom_arr而不元素比key此表達構建通過

  • reduce方法的新Array實例與空數組作爲累加器
  • 初始值
  • memo.any? { … } ? memo : memo+[denom]更大 - 如果存在至少累加器的一個元素,通過的塊爲真,保持累加器不變,否則附加值爲denom
  • {|coin| coin%denom==0 } - 如果coin可以被denom整除,則不會提醒,即傳遞給memo.any?的塊爲真。模數等於零

編輯: memo是保持的#reduce當前結果和用於可枚舉實例的每個元件被更新累加器

實施例:

denom_arr = [4,3,1] 
coins[123] # this invokes block passed to `Hash.new` to get default value 
# denom_arr.reject { |coin| coin > key }. 
# [4,3,1].reject { |coin| coin > 123 } 
# => [4,3,1] 
# .reduce([]) { |memo, denom| memo.any? {|coin| coin%denom==0 } ? memo : memo+[denom] }. 
# initialization: memo = [], denom = 4 
# 1st pass : memo.any? evaluates to false as memo is "empty" 
# memo = memo + [4] ie. memo == [4] now 
# 2nd pass : memo == [4], denom = 3 
# memo.any? evaluates to false as 4 % 3 != 0 
# memo = [4] + [3] => [4, 3] 
# 3rd pass : memo == [4,3], denom = 1 
# memo.any? evaluates to true as 4 % 1 == 0 
# memo = memo => [4, 3] 

希望它更清楚現在

+0

謝謝你的回答是「accumulator」這個計算機科學術語,因爲我對這個概念不熟悉,請你解釋一下。你也可以提供一個示例散列輸出嗎? **即。 denom_arr = 4,3,1和amt = 6第一次傳遞哈希的樣子是什麼?二次傳遞哈希是什麼樣子?在第三遍等等,直到完成...什麼是散列樣子?謝謝 – fyz

+0

大衛,這更清晰謝謝你!除了{| coin |硬幣> 123}'這是什麼?另外,這個例子是通過denom_arr的一個例子,但遞歸部分呢?你能證明這看起來如何嗎? +1的細分,但我仍然如此,這就是爲什麼我沒有接受你的答案。謝謝。 – fyz

+0

@go____yourself'[4,3,1] .reject {| coin |硬幣> 123}'表達式只是拋棄所有不會通過塊測試的元素,即。大於123,這是沒有那麼完整'[4,3,1]'返回。有關詳細信息,請參見[Array#reject](http://www.ruby-doc.org/core/Array.html#method-i-reject)。 –