假设我有两个项目列表。这两个列表的长度可能相同,也可能不同。
如何生成所有可能的项目对的所有列表,其中一对项目包含每个列表中的项目?每个项目只能在一对中。
所以,如果一个列表是:
(1, 2, 3)
另一个清单是:
(a, b)
然后所有可能的对的列表将是:
(1a, 2b)
(1a, 3b)
(1b, 2a)
(1b, 3a)
(2a, 3b)
(2b, 3a)
(我在Perl中实现了这一点,但显然算法很重要。)
提前致谢。我的递归foo无效!
答案 0 :(得分:0)
以下是示例代码。
use strict;
use warnings;
sub unordered_pairs {
return if @_ < 2;
my $first = shift;
return (map [$first, $_], @_), unordered_pairs(@_);
}
sub cartesian_product {
my @answers = [];
for my $list (@_) {
@answers = map {
my $value = $_;
map [@$_, $value], @answers
} @$list;
}
return @answers;
}
sub possible_pairs_of_pairs {
my ($list1, $list2) = @_;
my @pairs1 = unordered_pairs(@$list1);
my @pairs2 = unordered_pairs(@$list2);
return map {
[[$_->[0][0], $_->[1][0]], [$_->[0][1], $_->[1][1]]],
[[$_->[0][0], $_->[1][1]], [$_->[0][1], $_->[1][0]]],
} cartesian_product(\@pairs1, \@pairs2);
}
样本用法:
use Data::Dumper;
my @stuff = possible_pairs_of_pairs([1, 2, 3], ['a', 'b']);
print Dumper(\@stuff);
请注意,如果您的列表包含$n
和$m
元素,则最终输出将包含$n * ($n-1) * $m * ($m-1) / 2
个元素。使用较大的列表会很快爆炸。请阅读http://perl.plover.com/Stream/stream.html,了解如何使用这种数据结构不会耗尽内存。 (或阅读 Higher Order Perl ,这篇最终出自该文章的书。)