[svn:perlfaq] r10019 - perlfaq/trunk
[email protected] Fri, 28 Sep 2007 10:16:24 -0700 (PDT)
| Newsgroups | perl.cvs.perlfaq |
|---|---|
| Message-ID | <[email protected]> |
Author: comdog
Date: Fri Sep 28 10:16:23 2007
New Revision: 10019
Modified:
perlfaq/trunk/perlfaq4.pod
Log:
* perlfaq4: How do I permute N elements of a list?
+ Michele Dondi added an Algorithm::Loops example
+ I cleaned up some formatting
+ I added some index terms ( X<...> )
Modified: perlfaq/trunk/perlfaq4.pod
==============================================================================
--- perlfaq/trunk/perlfaq4.pod (original)
+++ perlfaq/trunk/perlfaq4.pod Fri Sep 28 10:16:23 2007
@@ -1588,14 +1588,18 @@
my $element = $array[ rand @array ];
=head2 How do I permute N elements of a list?
+X<List::Permuter> X<permute> X<Algorithm::Loops> X<Knuth>
+X<The Art of Computer Programming> X<Fischer-Krause>
-Use the C<List::Permutor> module on CPAN. If the list is actually an
+Use the C<List::Permutor> module on CPAN. If the list is actually an
array, try the C<Algorithm::Permute> module (also on CPAN). It's
-written in XS code and is very efficient.
+written in XS code and is very efficient:
use Algorithm::Permute;
+
my @array = 'a'..'d';
my $p_iterator = Algorithm::Permute->new ( \@array );
+
while (my @perm = $p_iterator->next) {
print "next permutation: (@perm)\n";
}
@@ -1603,16 +1607,17 @@
For even faster execution, you could do:
use Algorithm::Permute;
+
my @array = 'a'..'d';
+
Algorithm::Permute::permute {
print "next permutation: (@array)\n";
} @array;
-Here's a little program that generates all permutations of
-all the words on each line of input. The algorithm embodied
-in the C<permute()> function is discussed in Volume 4 (still
-unpublished) of Knuth's I<The Art of Computer Programming>
-and will work on any list:
+Here's a little program that generates all permutations of all the
+words on each line of input. The algorithm embodied in the
+C<permute()> function is discussed in Volume 4 (still unpublished) of
+Knuth's I<The Art of Computer Programming> and will work on any list:
#!/usr/bin/perl -n
# Fischer-Krause ordered permutation generator
@@ -1630,7 +1635,22 @@
}
}
- permute {print"@_\n"} split;
+ permute { print "@_\n" } split;
+
+The C<Algorithm::Loops> module also provides the C<NextPermute> and
+C<NextPermuteNum> functions which efficiently find all unique permutations
+of an array, even if it contains duplicate values, modifying it in-place:
+if its elements are in reverse-sorted order then the array is reversed,
+making it sorted, and it returns false; otherwise the next
+permutation is returned.
+
+C<NextPermute> uses string order and C<NextPermuteNum> numeric order, so
+you can enumerate all the permutations of C<0..9> like this:
+
+ use Algorithm::Loops qw(NextPermuteNum);
+
+ my @list= 0..9;
+ do { print "@list\n" } while NextPermuteNum @list;
=head2 How do I sort an array by (anything)?