硬币改变递归哈希(解释)?

时间:2014-06-10 21:26:45

标签: ruby algorithm recursion hash memoization

Ruby非贪婪的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] }(据我所知,它是一个硬币数组&lt; key)有人能告诉我一个如何分解的例子吗?

如果{|coin| coin%denom==0 }为真,则返回memo,但memo+[denom]究竟是什么?

我理解如果块返回false或nil以外的值,.any?方法如何返回true。

我认为memo是一个数组,但我在其上调用了类,它返回Class

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

总之,有人可以通过步骤中的示例输出来解释这个:

  • 这一行:.reduce([]) { |memo, denom| memo.any? {|coin| coin%denom==0 } ? memo : memo+[denom] }
  • 您能举例说明每次迭代时递归代码哈希键/值是什么吗? **

**即。 denom_arr = 4,3,1amt = 6在第一次传递时,哈希是什么样的?在第二次传递哈希看起来像什么?在第三遍等等,直到完成......哈希看起来像什么?

1 个答案:

答案 0 :(得分:1)

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

来自denom_arr且不包含大于key的元素此表达式通过

构建新的Array实例
  • reduce方法,其中一个空数组作为累加器的初始值
  • memo.any? { … } ? memo : memo+[denom] - 如果传递的块为真,则至少有一个累加器元素,保持累加器不变,否则将denom的值附加到它。
  • {|coin| coin%denom==0 } - 如果memo.any?可以被coin整除而没有提醒,则传递给denom的阻止为真。 modulo等于零

编辑: memo是累加器,它保存#reduce的当前结果,并针对Enumerable实例的每个元素进行更新

示例:

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]

希望现在更清楚