阵列的所有变体

时间:2014-10-17 18:04:54

标签: ruby-on-rails ruby arrays ruby-on-rails-3 combinatorics

我有一个像这样的结构数组:

  array = ["one","two","three","four"];

如何以所有可能的长度1-4获得此阵列的所有可能变体:

  ar = [["one"]["two"]["three"]["four"]["one","two"]
       ["one","three"] ["one","three","four"]]

我认为最后阵列中应该有4 * 4 * 4 * 4个元素。

5 个答案:

答案 0 :(得分:4)

  

如何获得此阵列的所有可能变体[...]

使用Array#combination

array.combination(3).to_a

结果:

[["one", "two", "three"],
 ["one", "two", "four"],
 ["one", "three", "four"],
 ["two", "three", "four"]]
  

[...]所有可能的长度1-4

使用范围,使用Enumerable#flat_map迭代它:

(1..array.length).flat_map {|len| array.combination(len).to_a }

结果:

[["one"],
 ["two"],
 ["three"],
 ["four"],
 ["one", "two"],
 ["one", "three"],
 ["one", "four"],
 ["two", "three"],
 ["two", "four"],
 ["three", "four"],
 ["one", "two", "three"],
 ["one", "two", "four"],
 ["one", "three", "four"],
 ["two", "three", "four"],
 ["one", "two", "three", "four"]]

答案 1 :(得分:1)

您正在寻找 组合动力

combinatorics gem执行此操作

["one","two","three","four"].powerset

答案 2 :(得分:1)

试试这个:

   def combinations(array)
      m = array.length
      (1...2**m).map do | n |
        (0...m).select { | i | n[i] == 1 }.map { | i | array[i] }
      end
    end

经过测试并得出结果:

irb(main):001:0> array = ["one","two", "three","four"];
irb(main):003:0> m = array.length
=> 4
irb(main):004:0> (1...2**m).map do |n|
irb(main):005:1* (0...m).select { |i| n[i] == 1}.map {|i| array[i]}
irb(main):006:1> end
=> [["one"], 
["two"], 
["one", "two"], 
["three"], 
["one", "three"], 
["two", "three"], 
["one", "two", "three"], 
["four"], 
["one", "four"], 
["two", "four"], 
["one", "two", "four"], 
["three", "four"], 
["one", "three", "four"], 
["two", "three","four"], 
["one", "two", "three", "four"]]

答案 3 :(得分:1)

哦,我想我自己找到了答案,我也可以将这些数组合起来:

a = [1, 2, 3, 4]
a.combination(1).to_a  #=> [[1],[2],[3],[4]]
a.combination(2).to_a  #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
a.combination(3).to_a  #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
a.combination(4).to_a  #=> [[1,2,3,4]]

答案 4 :(得分:1)

如果你说,结果应该有4 ** 4个元素,你可以这样做:

array = ["one", "two", "three", "four"]
  a = array.product(*[array]*(array.size-1))
  #=> [["one", "one", "one", "one"], ["one", "one", "one", "two"],
  #    ...
  #    ["four", "four", "four", "three"], ["four", "four", "four", "four"]]
a.size
  #=> 256
a.size == 4**4
  #=> true

但这与您的示例不一致。如果您不希望重复元素,但在结果中包含["one", "two"]["two", "one"]

a = (1..array.size).each_with_object([]) { |i,a|
      a.concat(array.permutation(i).to_a) }
  #=> [["one"], ["two"], ["three"], ["four"], 
  #    ["one", "two"], ["one", "three"], ["one", "four"], ["two", "one"],
  #    ["two", "three"], ["two", "four"], ["three", "one"], ["three", "two"],
  #    ["three", "four"], ["four", "one"], ["four", "two"], ["four", "three"],
  #    ["one", "two", "three"], ["one", "two", "four"],
  #    ...
  #
  #    ["four", "three", "one"], ["four", "three", "two"],
  #    ["one", "two", "three", "four"], ["one", "two", "four", "three"],
  #    ...
  #    ["four", "three", "one", "two"], ["four", "three", "two", "one"]]

a.size
  #=> 64
a.size == 4*3*2*1 + 4*3*2 + 4*3 + 4
  #=> true

最后,如果您想要元素的组合而不是元素的元素,只需将permuation替换为combination

a = (1..array.size).each_with_object([]) { |i,a|
      a.concat(array.combination(i).to_a) }
  #=> [["one"], ["two"], ["three"], ["four"],
  #    ["one", "two"], ["one", "three"], ["one", "four"],
  #      ["two", "three"], ["two", "four"], ["three", "four"],
  #    ["one", "two", "three"], ["one", "two", "four"],
  #      ["one", "three", "four"], ["two", "three", "four"],
  #    ["one", "two", "three", "four"]]
a.size
  #=> 15
a.size == 4*3*2/(1*(3*2)) + 4*3*2/(2*2) + 4*3*2/((3*2)*1) + 4*3*2/(4*3*2)
  #=> true
a.size == 2**4 - 1
  #=> true