在 Perl 中,如何迭代多个集合的笛卡尔积?
给定 x 个数组,每个数组可能具有不同数量的元素,如何迭代从每个数组中选择一项的所有组合?
示例:
[ ] [ ] [ ]
foo cat 1
bar dog 2
baz 3
4
返回
[foo] [cat] [ 1 ]
[foo] [cat] [ 2 ]
...
[baz] [dog] [ 4 ]
顺便说一句,我正在 Perl 中执行此操作。
Given x
number of arrays, each with a possibly different number of elements, how can I iterate through all combinations where I select one item from each array?
Example:
[ ] [ ] [ ]
foo cat 1
bar dog 2
baz 3
4
Returns
[foo] [cat] [ 1 ]
[foo] [cat] [ 2 ]
...
[baz] [dog] [ 4 ]
I'm doing this in Perl, btw.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我的 Set::CrossProduct 模块正是您想要的。 请注意,您实际上并不是在寻找排列,即集合中元素的排序。 您正在寻找叉积,它是来自不同集合的元素的组合。
我的模块为您提供了一个迭代器,因此您不必将其全部创建在内存中。 仅当需要时才创建新元组。
My Set::CrossProduct module does exactly what you want. Note that you aren't really looking for permutations, which is the ordering of the elements in a set. You're looking for the cross product, which is the combinations of elements from different sets.
My module gives you an iterator, so you don't create it all in memory. You create a new tuple only when you need it.
任意数量列表的简单递归解决方案:
任意数量列表的不那么简单的非递归解决方案:
A simple recursive solution for an arbitrary number of lists:
A not-so-simple non-recursive solution for an arbitrary number of lists:
用于计算笛卡尔积的递归且更流畅的 Perl 示例(带有注释和文档)可以在 http 中找到://www.perlmonks.org/?node_id=7366
示例:
Recursive and more-fluent Perl examples (with commentary and documentation) for doing the Cartesian product can be found at http://www.perlmonks.org/?node_id=7366
Example:
您可以使用嵌套循环。
当需要任意数量的嵌套循环时,可以使用 Algorithm::Loops的
NestedLoops
。You can use nested loops.
When you need an arbitrary number of nested loops, you can use Algorithm::Loops's
NestedLoops
.我首先想到的一种方法是使用几个 for 循环并且不使用递归。
示例:
给定 A[3], B[2], C[3 ],
当然可以用 for 循环代替 [ABC ...] 循环,并且可以记住一小部分。 当然,递归更简洁,但这对于递归受到堆栈大小严重限制的语言可能很有用。
There's one method I thought of first that uses a couple for loops and no recursion.
Example:
Given A[3], B[2], C[3],
where of course a for loop can be substituted to loop over [A B C ...], and a small part can be memoized. Of course, recursion is neater, but this might be useful for languages in which recursion is severely limited by stack size.