【问题标题】:Ruby Unique combinations of 2 from n arrays of different sizesRuby 不同大小的 n 个数组中的 2 个的独特组合
【发布时间】:2017-01-11 16:15:33
【问题描述】:

我有一个 n 个数组,它们的大小都可能不同。我需要通过使用每个数组中的不超过一个值来计算 2 的可能组合并打印总数。例如:

我有:

n = 3, in arr[n]
arr = [[0, 1], [2, 3, 4], [5, 6, 7, 8]]

我想得到:

[0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8],
[1, 8], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [1, 8],
[3, 5], [3, 6], [3, 7], [3, 8], 
[4, 5], [4, 6], [4, 7], [4, 8], etc.

return number of arrays

在数学上,我相信这是 xy + xz + y*z 或:

arr[0].size * arr[1].size + arr[0].size * arr[2].size + arr[1].size * arr[2].size

如果我的公式有误,请随时纠正我。

无论如何,对于未知的 n 数组,我该如何实现呢?

【问题讨论】:

  • 我没有遵循你的公式,你是如何推导出 [0,2],[0.3] 等的
  • 0 是 arr[0] 的值,2 是 arr[1] 的值,3 是 arr[1] 的值。所以我需要从 arr[0] 中提取不超过一个值,从 arr[1] 中提取不超过一个值,并且从 arr[2] 中提取不超过一个值来创建两个值的组合。所以没有 arr[0] 和 arr[0] 的组合,也没有 arr[1] 和 arr[1] 等的组合。我需要对 arr[n] 中的变量 n 执行此操作。

标签: arrays ruby combinations arrayofarrays


【解决方案1】:

数组

您可以使用combination 和笛卡尔product

arrays = [[0, 1], [2, 3, 4], [5, 6, 7, 8]]

p arrays.combination(2).flat_map{ |a, b| a.product(b) }.sort
#=> [[0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4], [0, 5], [0, 6], [0, 7], [0, 8], [1, 5], [1, 6], [1, 7], [1, 8], [2, 5], [2, 6], [2, 7], [2, 8], [3, 5], [3, 6], [3, 7], [3, 8], [4, 5], [4, 6], [4, 7], [4, 8]]

p arrays.combination(2).flat_map{ |a, b| a.product(b) }.sort
#=> [[0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [1, 8], [2, 5], [2, 6], [2, 7], [2, 8], [3, 5], [3, 6], [3, 7], [3, 8], [4, 5], [4, 6], [4, 7], [4, 8]]

p arrays.combination(2).flat_map{|a,b| a.product(b)}.size
#=> 26

在数组上调用combination(2) 会输出所有唯一的子数组对。 对于每对数组,第一个数组的每个元素都与第二个数组的每个元素匹配(请参阅Cartesian product)。

flat_map在这里是为了避免得到数组数组的数组。

尺寸

使用组合

您的公式对于 3 个子数组是正确的。对于n数组,你需要列出两个子数组的所有组合,并将它们各自大小的乘积相加:

p arrays.map(&:size).combination(2).map{|s1, s2| s1*s2}.inject(:+)
#=> 26

另类

利用(x+y+z)**2的扩展版本是

x**2 + 2*xy + y**2 + 2*xz + 2*yz + z**2

我们看到了:

2*xy + 2*xz + 2*yz = (x+y+z)**2 - (x**2 + y**2 + z**2)

所以

xy + xz + yz = ( (x+y+z)**2 - (x**2 + y**2 + z**2) )/2

它看起来不像是 3 个值的快捷方式,但它可以推广到 n 数组,并帮助我们完全避免 combination

sizes = arrays.map(&:size)
p (sizes.inject(:+)**2 - sizes.map{|s| s**2}.inject(:+))/2
#=> 26

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    相关资源
    最近更新 更多