【问题标题】:Coin change recursive hash (explained)?硬币改变递归哈希(解释)?
【发布时间】:2014-06-10 21:26:45
【问题描述】:

Ruby non-greedy memoized hash,硬币找零解决方案:

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 } 是真的返回memomemo+[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 在第一遍中,哈希是什么样的?在第二遍时,哈希是什么样的?在第三遍等直到完成......哈希是什么样的?

【问题讨论】:

  • @quetzalcoatl 我认为它更适合我,因为 codereview 对我来说表明我理解代码并希望优化它,而 SO 更多的是 帮助我理解这一点 一种论坛。

标签: ruby algorithm recursion hash memoization


【解决方案1】:
.reduce([]) { |memo, denom| memo.any? {|coin| coin%denom==0 } ? memo : memo+[denom] }

从没有大于key 的元素的denom_arr 开始,此表达式通过

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

编辑: 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]

希望现在更清楚

【讨论】:

  • 谢谢你的回答是“累加器”一个计算机科学术语,因为我不熟悉这个概念,请你解释一下。您还可以提供一个示例哈希输出吗? ** IE。 denom_arr = 4,3,1 和 amt = 6 在第一遍中,散列是什么样的?在第二遍时,散列是什么样的?在第三遍等直到完成......哈希是什么样的?谢谢
  • 大卫,这更清楚了,谢谢!除了{ |coin| coin &gt; 123 } 这是什么?另外,这个例子是一次通过denom_arr,但是递归部分呢?你也能展示一下它的样子吗? +1 表示故障,但我仍然对此持怀疑态度,这就是为什么我没有接受你的回答。谢谢。
  • @go____yourself [4,3,1].reject { |coin| coin &gt; 123 } 表达式只是丢弃所有不会通过块中测试的元素,即。大于 123 ,因此返回完整的 [4,3,1]。详情请见Array#reject
  • 大卫,我知道它是什么,但为什么是 123?您只是使用该值来说明您的示例吗?我的问题是 123 如何与 coin_change 代码相关联?
  • 是的,这个数字只是一个例子,需要演示代码流。我可以在你的问题中使用6,但它不会改变任何东西。
猜你喜欢
  • 1970-01-01
  • 2018-10-07
  • 2020-04-11
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 2023-03-02
  • 1970-01-01
  • 2016-11-20
相关资源
最近更新 更多