查找数组中添加到指定值的所有值

时间:2014-11-11 19:34:26

标签: ruby add

如果您有目标编号和值数组,那么如何找到所有符合目标值的数字组合?

target_number = 42
sample_values = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]

这里的答案是:

14 + 28 = 42
13 + 27 = 42
12 + 26 = 42
...
1 + 13 + 28 = 42
2 + 12 + 28 = 42
...

我确信这种类型的搜索有一个数学术语,可能是一个ruby库来为你做这件事。

如果没有嵌套for循环,你怎么做?

sample_values.each do | x | 
  sample_values.each do | i | 
    sample_values.each do | j | 
      if x + i + j == target_number
        puts "#{x} + #{i} + #{j} is #{target_number}" 
      end
    end
  end
end

2 个答案:

答案 0 :(得分:3)

这是Subset Sum问题。

另请查看Ruby combination方法。

快速执行此操作的方法是:

a = [1,2,3,4,5]  
arr = []
numOfCombinations = 0

for i in 0..(a.length) do
  a.combination(i).each do |b|
    c = b.reduce(:+)
      if c == target_number
        numOfCombinations += 1
      end
  end
end

note: this is slow with a large number array

答案 1 :(得分:1)

target_number = 42
sample_values = (1..28).to_a

(1..sample_values.length).
  map { |length| sample_values.combination(length).to_a.
    select { |candidate| candidate.reduce(:+) == target_number }
  }.flatten(1)

代码迭代从1到sample_values长度的数字范围,生成每个长度的所有组合,然后仅过滤掉与target_number相加的组合,然后从中删除一个级别的嵌套结果

请注意,对1到28之间的数字组执行此操作需要时间。将示例更改为仅使用数字1到20会在几秒钟内产生结果:

=> [[3, 19, 20], [4, 18, 20], [5, 17, 20], [5, 18, 19], [6, 16, 20], [6, 17, 19], [7, 15, 20], [7, 16, 19], [7, 17, 18], [8, 14, 20], [8, 15, 19], [8, 16, 18], [9, 13, 20], [9, 14, 19], [9, 15, 18], [9, 16, 17], [10, 12, 20], [10, 13, 19], [10, 14, 18], [10, 15, 17], [11, 12, 19], [11, 13, 18], [11, 14, 17], [11, 15, 16], [12, 13, 17], [12, 14, 16], [13, 14, 15], [1, 2, 19, 20], [1, 3, 18, 20], [1, 4, 17, 20], [1, 4, 18, 19], [1, 5, 16, 20], [1, 5, 17, 19], [1, 6, 15, 20], [1, 6, 16, 19], [1, 6, 17, 18], [1, 7, 14, 20], [1, 7, 15, 19], ...