3倍更快,使用的内存更少(回收更少).
cartesian: func [ d [block! ] /local len set i res ][ d: copy d len: 1 res: make block! foreach d d [len: len * length? d] len: length? d until [ set: clear [] loop i: len [insert set d/:i/1 i: i - 1] res: change/only res copy set loop i: len [ unless tail? d/:i: next d/:i [break] if i = 1 [break] d/:i: head d/:i i: i - 1 ] tail? d/1 ] head res ]
这样的事情怎么样:
#!/usr/bin/perl use strict; use warnings; my @list1 = qw(1 2); my @list2 = qw(3 4); my @list3 = qw(5 6); # Calculate the Cartesian Product my @cp = cart_prod(\@list1, \@list2, \@list3); # Print the result foreach my $elem (@cp) { print join(' ', @$elem), "\n"; } sub cart_prod { my @sets = @_; my @result; my $result_elems = 1; # Calculate the number of elements needed in the result map { $result_elems *= scalar @$_ } @sets; return undef if $result_elems == 0; # Go through each set and add the appropriate element # to each element of the result my $scale_factor = $result_elems; foreach my $set (@sets) { my $set_elems = scalar @$set; # Elements in this set $scale_factor /= $set_elems; foreach my $i (0 .. $result_elems - 1) { # Calculate the set element to place in this position # of the result set. my $pos = $i / $scale_factor % $set_elems; push @{$result[$i]}, $$set[ $pos ]; } } return @result; }
其中产生以下输出:
1 3 5 1 3 6 1 4 5 1 4 6 2 3 5 2 3 6 2 4 5 2 4 6