Power set: Difference between revisions

Content added Content deleted
(Undo revision 188585 by Siskus (talk))
(→‎{{header|Perl}}: Added lower memory implementation.)
Line 1,671: Line 1,671:


print set_to_string(@powerset), "\n";</lang>
print set_to_string(@powerset), "\n";</lang>
{{out}}

<pre>
<pre>
{{}, {1}, {2}, {1, 2}, {3}, {1, 3}, {2, 3}, {1, 2, 3}}
{{}, {1}, {2}, {1, 2}, {3}, {1, 3}, {2, 3}, {1, 2, 3}}
</pre>
</pre>

<li><p>'''''Use lazy evaluation'''''</p>
If the initial set is quite large, constructing it's powerset can consume lots of memory.

If you want to iterate through all of the elements of the powerset of a set, and don't mind each element being generated immediately before you process it, and being thrown away immediately after you're done with it, you can use vastly less memory.

The following algorithm uses one bit of memory for every element of the original set.

<lang perl>use strict;
use warnings;
sub powerset(&@) {
my $callback = shift;
my $bitmask = '';
my $bytes = @_/8;
{
my @indices = grep vec($bitmask, $_, 1), 0..$#_;
$callback->( @_[@indices] );
++vec($bitmask, $_, 8) and last for 0 .. $bytes;
redo if @indices != @_;
}
}

print "powerset of empty set:\n";
powerset { print "[@_]\n" };
print "powerset of set {1,2,3,4}:\n";
powerset { print "[@_]\n" } 1..4;
my $i = 0;
powerset { ++$i } 1..9;
print "The powerset of a nine element set contains $i elements.\n";
</lang>
{{out}}
<pre>powerset of empty set:
[]
powerset of set {1,2,3,4}:
[]
[1]
[2]
[1 2]
[3]
[1 3]
[2 3]
[1 2 3]
[4]
[1 4]
[2 4]
[1 2 4]
[3 4]
[1 3 4]
[2 3 4]
[1 2 3 4]
The powerset of a nine element set contains 512 elements.

</pre>
The technique shown above will work with arbitrarily large sets, and uses a trivial amount of memory.


</li>
</li>