2014-06-10 65 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)。 –