带数组的递归函数

时间:2015-03-11 12:25:39

标签: ruby

我有一个包含以下示例定义的数组:

segments = [["000", "001", "002"], ["110", "111", "112"], ["210", "211", "212"]]

此数组可以包含任意数量的元素,每个元素都有一个数组。

我正在尝试生成以下输出:

000-110-210
000-110-211
000-110-212
000-111-210
000-111-211
000-111-212
000-112-210
000-112-211
000-112-212
001-110-211
001-110-212
001-111-210
001-111-211
001-111-212
001-112-210
001-112-211
001-112-212
.
.
.

我无法弄清楚完成这项工作的逻辑。

3 个答案:

答案 0 :(得分:8)

您可以使用Array#product

combined = segments[0].product(*segments[1..-1]) 
#=> [["000", "110", "210"], ["000", "110", "211"], ["000", "110", "212"],
#    ["000", "111", "210"], ["000", "111", "211"], ["000", "111", "212"],
#    ["000", "112", "210"], ["000", "112", "211"], ["000", "112", "212"],
#    ["001", "110", "210"], ["001", "110", "211"], ["001", "110", "212"],
#    ["001", "111", "210"], ["001", "111", "211"], ["001", "111", "212"],
#    ["001", "112", "210"], ["001", "112", "211"], ["001", "112", "212"],
#    ["002", "110", "210"], ["002", "110", "211"], ["002", "110", "212"],
#    ["002", "111", "210"], ["002", "111", "211"], ["002", "111", "212"],
#    ["002", "112", "210"], ["002", "112", "211"], ["002", "112", "212"]]

或者更明确地说明(如果数组的数量是固定的):

combined = segments[0].product(segments[1], segments[2])

使用join加入子数组:

combined.map { |arr| arr.join('-') }
#=> ["000-110-210", "000-110-211", "000-110-212", ...]

答案 1 :(得分:1)

如果你只需要结果 - 请使用@Stefan回答。如果这只是更大的开始和/或你想了解如何自己做:

segments = [["000", "001", "002"], ["110", "111", "112"], ["210", "211", "212"]]

def generate(segments, i, cur)
  if i == segments.count
    puts cur.join("-")
    return
  end

  0.upto(segments[i].count - 1) do |j|
    cur << segments[i][j]
    generate(segments, i + 1, cur)
    cur.pop
  end
end

generate(segments, 0, [])

答案 2 :(得分:1)

您可以使用Array#product,它将为您提供数组的交叉产品。当给出时,产品将产生所有组合并返回self。

试试这个:

combinations = []
segments.first.product(*segments[1..-1]) { |arr| combinations << arr.join("-") }

输出将是:

combinations
=> ["000-110-210", "000-110-211", "000-110-212", "000-111-210", "000-111-211", "000-111-212", "000-112-210", "000-112-211", "000-112-212", "001-110-210", "001-110-211", "001-110-212", "001-111-210", "001-111-211", "001-111-212", "001-112-210", "001-112-211", "001-112-212", "002-110-210", "002-110-211", "002-110-212", "002-111-210", "002-111-211", "002-111-212", "002-112-210", "002-112-211", "002-112-212"]