【问题标题】:How to recursively find permutations of two dimensional array in Ruby如何在Ruby中递归查找二维数组的排列
【发布时间】:2025-12-12 03:50:02
【问题描述】:

我有一个数组,其中的元素是不同大小的数组。例如:

[[3],[11,2],[11,2],[3]]

我想找到嵌套数组中所有单个项目的排列。对于上面的数组,我想要一个返回值:

[
  [3, 11, 11, 3],
  [3, 11, 2, 3],
  [3, 2, 11, 3],
  [3, 2, 2, 3]
]

我有一个可行的解决方案,但似乎特别冗长:

array = [[3],[11,2],[11,2],[3]]
array.product(*array).map { |e| e.drop(1) }.uniq

我应该如何为此实现递归方法,它如何工作?我很难理解这一点。

【问题讨论】:

    标签: arrays ruby algorithm recursion multidimensional-array


    【解决方案1】:

    解决这个问题的常规方法是使用Array#productArray#drop的方法。

    arr = [[3], [11,2], [11,2,7], [4]]
    
    arr.first.product(*arr.drop(1))
      #=> [[3, 11, 11, 4], [3, 11, 2, 4], [3, 11, 7, 4],
      #    [3, 2, 11, 4], [3, 2, 2, 4], [3, 2, 7, 4]]
    

    如果arr 的任何元素包含重复项,则返回值也将包含重复项。如果不需要重复,请使用

    arr.map(&:uniq).first.product(*arr.drop(1))
    

    但是,提问者请求递归解决方案。可以这样写:

    def prod(arr)
      return arr if arr.size == 1
      t = prod(arr.drop(1))
      arr.first.flat_map { |x| t.map { |a| [x] + a } }
    end
    
    prod arr
      #=> [[3, 11, 11, 4], [3, 11, 2, 4], [3, 11, 7, 4],
      #    [3, 2, 11, 4], [3, 2, 2, 4], [3, 2, 7, 4]]
    

    【讨论】:

    • 我无法确定这是否是骗局。答案是相同的,至少:*.com/a/43748139/2988
    • @JörgWMittag,我称它为 dup。事实上,这可能是多次重复。
    • 我正在寻找递归。这个答案没有显示递归,所以它不是我的问题的答案,也不是上面链接的欺骗。
    • @Jörg 思考这个问题——不是我的答案——是否是一个骗局。根据我的经验,当提问者规定解决问题的特定方法时,通常意味着他/她已经假设——也许是错误的——必须使用所述方法来解决问题。 (它很常见,以至于有一个名字:x-y problem"。)因此,(如这里)读者通常会提供他们认为是问题的最佳解决方案,无论它是否采用所述方法。 (续)
    • ...您当然可以要求采用特定方法的解决方案。我已经编辑了我的答案以展示如何使用递归。
    【解决方案2】:

    初始化:

    @arr = [[3],[11,2],[11,2],[3]]
    @perms = []
    

    功能定义:

    def recursion(idx, temp = [])
        if (idx == @arr.size) then @perms.push(temp.clone); return end
        @arr[idx].each { |x|  recursion(idx+1, temp << x); temp.pop }
    end
    

    致电:

    recursion(0)
    p @perms
     => [[3, 11, 11, 3], [3, 11, 2, 3], [3, 2, 11, 3], [3, 2, 2, 3]]
    

    【讨论】: