在 Ruby 中将数组的数组组合成所有可能的组合(仅向前)

发布于 2024-10-20 15:51:20 字数 369 浏览 1 评论 0原文

我有一个数组数组,如下所示:

[['1','2'],['a','b'],['x','y']]

我需要将这些数组组合成一个字符串,其中包含所有三个集合的所有可能组合(仅向前)。我已经看到了很多以任何顺序组合所有可能组合的例子,这不是我想要的。例如,我不希望第一组中的任何元素出现在第二组之后,或者第三组中的任何元素出现在第一组或第二组之前,依此类推。因此,对于上面的示例,输出将是:

['1ax', '1ay', '1bx', '1by', '2ax', '2ay', '2bx', '2by']

数组的数量和每组的长度是动态的。

有人知道如何用 Ruby 解决这个问题吗?

I have an array of arrays, like so:

[['1','2'],['a','b'],['x','y']]

I need to combine those arrays into a string containing all possible combinations of all three sets, forward only. I have seen lots of examples of all possible combinations of the sets in any order, that is not what I want. For example, I do not want any of the elements in the first set to come after the second set, or any in the third set to come before the first, or second, and so on. So, for the above example, the output would be:

['1ax', '1ay', '1bx', '1by', '2ax', '2ay', '2bx', '2by']

The number of arrays, and length of each set is dynamic.

Does anybody know how to solve this in Ruby?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小…楫夜泊 2024-10-27 15:51:20

了解您的Array#product

a = [['1','2'],['a','b'],['x','y']]
a.first.product(*a[1..-1]).map(&:join)

Know your Array#product:

a = [['1','2'],['a','b'],['x','y']]
a.first.product(*a[1..-1]).map(&:join)
去了角落 2024-10-27 15:51:20

使用递归的、所谓的“动态编程”方法来解决:

  • 对于 n 数组,结合第一个数组的条目与剩余 (n-1) 个数组上的每个结果
  • 对于单个数组,答案就是该数组

在代码中:

def variations(a)
  first = a.first
  if a.length==1 then
    first
  else
    rest = variations(a[1..-1])
    first.map{ |x| rest.map{ |y| "#{x}#{y}" } }.flatten
  end
end

p variations([['1','2'],['a','b'],['x','y']])
#=> ["1ax", "1ay", "1bx", "1by", "2ax", "2ay", "2bx", "2by"]

puts variations([%w[a b],%w[M N],['-'],%w[x y z],%w[0 1 2]]).join(' ')
#=> aM-x0 aM-x1 aM-x2 aM-y0 aM-y1 aM-y2 aM-z0 aM-z1 aM-z2 aN-x0 aN-x1 aN-x2
#=> aN-y0 aN-y1 aN-y2 aN-z0 aN-z1 aN-z2 bM-x0 bM-x1 bM-x2 bM-y0 bM-y1 bM-y2
#=> bM-z0 bM-z1 bM-z2 bN-x0 bN-x1 bN-x2 bN-y0 bN-y1 bN-y2 bN-z0 bN-z1 bN-z2

您也可以反转逻辑,并且小心地您应该能够实现这个非-递归地。但递归的答案相当简单。 :)

Solved using a recursive, so-called "Dynamic Programming" approach:

  • For n-arrays, combine the entries of the first array with each result on the remaining (n-1) arrays
  • For a single array, the answer is just that array

In code:

def variations(a)
  first = a.first
  if a.length==1 then
    first
  else
    rest = variations(a[1..-1])
    first.map{ |x| rest.map{ |y| "#{x}#{y}" } }.flatten
  end
end

p variations([['1','2'],['a','b'],['x','y']])
#=> ["1ax", "1ay", "1bx", "1by", "2ax", "2ay", "2bx", "2by"]

puts variations([%w[a b],%w[M N],['-'],%w[x y z],%w[0 1 2]]).join(' ')
#=> aM-x0 aM-x1 aM-x2 aM-y0 aM-y1 aM-y2 aM-z0 aM-z1 aM-z2 aN-x0 aN-x1 aN-x2
#=> aN-y0 aN-y1 aN-y2 aN-z0 aN-z1 aN-z2 bM-x0 bM-x1 bM-x2 bM-y0 bM-y1 bM-y2
#=> bM-z0 bM-z1 bM-z2 bN-x0 bN-x1 bN-x2 bN-y0 bN-y1 bN-y2 bN-z0 bN-z1 bN-z2

You could also reverse the logic, and with care you should be able to implement this non-recursively. But the recursive answer is rather straightforward. :)

—━☆沉默づ 2024-10-27 15:51:20

纯、还原产物:

a = [['1','2'],['a','b'],['x','y']]
a.reduce() { |acc, n| acc.product(n).map(&:flatten) }.map(&:join)
#  => ["1ax", "1ay", "1bx", "1by", "2ax", "2ay", "2bx", "2by"]

Pure, reduce with product:

a = [['1','2'],['a','b'],['x','y']]
a.reduce() { |acc, n| acc.product(n).map(&:flatten) }.map(&:join)
#  => ["1ax", "1ay", "1bx", "1by", "2ax", "2ay", "2bx", "2by"]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文