How can I generate all subsets of a list in Perl?

I have a math set in a Perl array: (1, 2, 3). I would like to find all the subsets of this set: (1), (2), (3), (1,2), (1,3), (2,3).

With 3 elements, this is not too difficult, but if there are 10 elements in the set, it becomes difficult.

Thoughts?

+5
source share
6 answers

You can use Data :: PowerSet , as Matthew mentioned. However, if, as indicated in your example, you want only the correct subsets, and not all subsets, you need to do a little more work.

  # result: all subsets, except {68, 22, 43}.
  my $values = Data::PowerSet->new({max => 2}, 68, 22, 43);

Similarly, if you want to omit null dialing, just add a parameter min:

  # result: all subsets, except {} and {68, 22, 43}.
  my $values = Data::PowerSet->new({min => 1, max => 2}, 68, 22, 43);

, , :

  # result: every subset.
  my $values = Data::PowerSet->new(68, 22, 43);
+12

" ", , , .

, 32 :

my $set = [1,2,3];
my @subsets;
for my $count ( 1..(1<<@$set)-2 ) {
    push @subsets, [ map $count & (1<<$_) ? $set->[$_] : (), 0..$#$set ];
}

( 0 (1 < @$set) -1, 0, , (1 < @$set) -1 .)

: , , , , ​​. , , . , , , . " ". , . . , . , . , , , , - .

+3

, , bit-mask . -

#!/usr/bin/perl
use strict;
use warnings;

my @set     = (1, 2, 3);
my @bitMask = (0, 0, 0); #Same size as @set, initially filled with zeroes

printSubset(\@bitMask, \@set) while ( genMask(\@bitMask, \@set) );

sub printSubset {
  my ($bitMask, $set) = @_;

  for (0 .. @$bitMask-1) {
    print "$set->[$_]" if $bitMask->[$_] == 1;
  }
  print"\n";

}

sub genMask {
  my ($bitMask, $set) = @_;

  my $i;
  for ($i = 0; $i < @$set && $bitMask->[$i]; $i++) {
    $bitMask->[$i] = 0;
  }

  if ($i < @$set) {
    $bitMask->[$i] = 1;
    return 1;
  }

  return 0;
}

. , .

+1

- N 2 ^ N , 0 2 ^ N - 1 , .

, 8 : 000, 001, 010, 011, 100, 101, 110 111 - , .

+1

All Articles