【问题标题】:Generating combinations from an array which == a specified amount?从 == 指定数量的数组生成组合?
【发布时间】:2014-07-26 19:13:07
【问题描述】:

我需要从denom_arr 中获取所有可能的数字组合,它们等于amt

denom_arr = [4,3,1]
amt = 10

这种情况会产生:

  1. [4, 4, 1, 1]
  2. [3, 3, 3, 1]
  3. [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
  4. [4, 3, 1, 1, 1]
  5. [4, 3, 3]
  6. 。 . . (其他情况...)

问题是我写的代码在 1-3 之后被破坏了,我不知道如何让它在同一个索引上循环以获取 case 4-6+

set, sets = [], []
i = 0
loop do
i = 0 if denom_arr[i].nil? 

  loop do
    set << denom_arr[i]
    break if set.inject(:+) > amt
  end

  set.pop if set.inject(:+) > amt

  if set.inject(:+) == amt
    sets << set
    set = []
    denom_arr.shift
  end

i += 1
sets
break if denom_arr.empty?
end 

更新

我知道这可以通过使用记忆/动态编程技术的递归来完成,但为了测试理论,我正试图严格地在循环中执行此操作。

【问题讨论】:

  • [4,3,1,1,1] 怎么样?
  • @BroiSatse 是的很好。我觉得我错过了一些东西。问题更新了。
  • 还有很多其他情况:4 和 1,两个 3 和 1,一个 3 和 1,...
  • @MxyL 是的,正确...我只是真的关心最短的情况..
  • 那是什么理论?

标签: ruby arrays algorithm


【解决方案1】:

我会递归地这样做

def possible_sums(arr, amt)
  return [[]] if amt == 0
  return []   if amt < 0

  arr.reduce([]) do |sums, e|
    sums.concat(
      possible_sums(arr, amt-e)
        .map { |sum| sum.unshift(e).sort }
    )
  end.uniq
end

p possible_sums([4,3,1], 10)
  # => [
  #      [1, 1, 4, 4], [3, 3, 4], [1, 1, 1, 3, 4], [1, 1, 1, 1, 1, 1, 4], 
  #      [1, 3, 3, 3], [1, 1, 1, 1, 3, 3], [1, 1, 1, 1, 1, 1, 1, 3], 
  #      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
  #    ]

虽然这可能会因为重复工作而导致效率低下,但可以通过使用动态编程(本质上是记忆递归函数的结果)来缓解这种情况。

更新这是一个迭代解决方案:

def possible_sums_it(arr, amt)
  sums = Array.new(amt+1) { [] }
  sums[0] << []

  (1..amt).each do |i|
    arr.each do |e|
      if i-e >= 0
        sums[i].concat(
          sums[i-e].map { |s| [e, *s].sort }
        )
      end
    end

    sums[i].uniq!
  end

  sums[amt]
end

这其实就是问题的动态规划算法。

所以,如果你眯着眼睛看它,你会发现它本质上是在计算 0amt 的所有可能的总和到 sums 数组中,基本上是递归算法,但不是递归调用,而是在sums 中查找我们事先计算好的值。

这是可行的,因为我们知道在 sums[j] 之前我们不需要 sums[i] 来代替 j &lt; i

【讨论】:

  • 是的,我知道递归和记忆/动态技术。我严格地尝试在循环中做同样的事情,只是为了比较执行速度。
  • 您应该在问题中明确说明这一点。
  • @go____yourself 有你的迭代解决方案。
  • 很好的解决方案..如果你能解释一下..那将不胜感激。
  • @go____yourself 添加了解释。
猜你喜欢
  • 2013-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 2022-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多