Ruby 如何创建从多个数组中选择的单个元素的每个组合?

Ruby 如何创建从多个数组中选择的单个元素的每个组合?,ruby,arrays,combinatorics,Ruby,Arrays,Combinatorics,我有5个阵列: ["A", "B", "C"] ["A", "B", "C", "D", "E"] ["A"] ["A", "B", "C", "D", "E", "F"] ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"] 我想创建每个组合的列表,如下所示: ["AAAAA","AAAAB","AAAAC", "AAAAD"... "BAAAA","BAAAB","BAAAC", "BAAA

我有5个阵列:

["A", "B", "C"]
["A", "B", "C", "D", "E"]
["A"]
["A", "B", "C", "D", "E", "F"]
["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"]
我想创建每个组合的列表,如下所示:

["AAAAA","AAAAB","AAAAC", "AAAAD"...
 "BAAAA","BAAAB","BAAAC", "BAAAD"...]

感谢bluexuemei改进了答案。最初的解决方案是
a.shift.product(*a).map(&:join)


更传统的解决方案 有了这样一个方便的库,这些ruby one行程序看起来几乎像是作弊

这里有一种更传统的方法来解决这个常见问题,它可以很容易地编码到其他编程语言中:

N = a.reduce(1) { |product,list| product * list.size } # 1350

combinations = []
0.upto(N-1) do |q|
  combo = []
  a.reverse.each do |list|
    q, r = q.divmod list.size
    combo << list[r]
  end
  combinations.push combo.reverse.join
end
combinations
# => ["AAAAA", "AAAAB", "AAAAC", ..., "CEAFM", "CEAFN", "CEAFO"]
N=a.reduce(1){| product,list | product*list.size}1350
组合=[]
0.高达(N-1)do | q|
组合=[]
a、 反向。每个do |列表|
q、 r=q.divmod list.size
组合[“AAAAA”、“AAAAB”、“AAAAC”、…、“CEAFM”、“CEAFN”、“CEAFO”]

基本思想是首先计算组合的总数
N
,它只是所有列表长度的乘积。然后,从
0
N-1
的每个整数将提供唯一索引所需的所有信息编码到每个列表中,以生成每个组合。一种考虑方法是,索引变量
q
可以表示为一个5位数字,其中每个数字位于不同的基数中,基数是相应列表的大小。也就是说,第一个数字是base-3,第二个数字是base-5,第三个数字是base-1(始终为0),第四个数字是base-6,第五个数字是base-15。要从
q
中提取这些值,只需使用一系列重复的整数除法和余数,就像在内部循环中一样。当然,这需要一些家庭作业,也许是看一些更简单的例子,才能完全消化。

所以。。。你需要每一个元素的组合?你尝试了什么?你遇到了什么具体问题?你是如何得到第二个数组…在哪种逻辑下?@YoursTruly,显而易见的解决方案是:N个嵌套循环(在你的例子中N=5)a在这里做什么?:a.shift.product(*a).map(&:join)@YoursTruly
a.shift
删除并返回第一个数组,然后调用其余4个数组。为了将剩余的4个数组作为4个分离参数而不是单个数组传递,这就是*所做的。它被称为“splat”操作符,因为它将数组展开成参数,而没有周围的[]s.+1很好的答案,比
shift
/splat方法更好。
a.reduce(&:product).map(&:join).size
a.reduce(&:product).map(&:join).size