如何在Perl中查找有序符号的所有组合

时间:2014-08-13 02:41:06

标签: perl

说我有一套信件。

my @set = qw( A C E );

如何找到此套装中所有有序字母的组合

A C E
A C
A E
C E
A
C
E

集合中的符号数量会有所不同。

5 个答案:

答案 0 :(得分:2)

使用CPAN中的Algorithm::Combinatorics模块

#!/usr/bin/perl
use strict;
use warnings;
use Algorithm::Combinatorics qw(combinations);

my @set = qw( A C E );

for my $num (1 .. +@set) {
    my $combination = combinations(\@set, $num);
    while (my $pair = $combination->next) {
        print "@$pair\n";
    }
}

输出:

A
C
E
A C
A E
C E
A C E

答案 1 :(得分:1)

以下是根据要求提供组合的代码。在评论中,OP表示他实际上想要排列。如果这真的是他想要的,可以通过NextPermute从同一模块轻松获得它们。


由于您没有重复符号,您可以使用以下内容:

my @set = qw( A C E );

say "{}";
for my $s1 (0..$#set) {
   say "{", join(',', $set[ $s1 ]), "}";
   for my $s2 ($s1+1..$#set) {
      say "{", join(',', @set[ $s1, $s2 ]), "}";
      for my $s3 ($s2+1..$#set) {
         say "{", join(',', @set[ $s1, $s2, $s3 ]), "}";
      }
   }
}   

但是假设你知道集合中的符号数量。我们可以使用NestedLoops为我们构建这些嵌套循环。

use Algorithm::Loops qw( NestedLoops );

my @set = qw( A C E );

my $iter = NestedLoops(
   [
      [ 0..$#set ],
      ( sub { [ $_+1..$#set ] } ) x $#set,
   ],
   { OnlyWhen => 1 },
);

say "{}";
while (my @c = $iter->()) {
   say "{", join(',', @set[@c]), "}";
}

两个输出

{}
{A}
{A,C}
{A,C,E}
{A,E}
{C}
{C,E}
{E}

答案 2 :(得分:0)

Funny Question ! 
 But I can not use perl This is C .
I come from China, please forgive my English.
#include<stdio.h>

char chars[27];
int bitstatus[27];
int countbits(char* words);
void func(int id,int count,int* countstatus,char* chars);
int main(){ 
    printf("Input chars with no blank:");
    scanf("%s",chars);
    int count=countbits(chars);
    func(1,count,bitstatus,chars);  
return 0;
}

int countbits(char* words){
    int count=0;
    while(*words++)
        count++;
return count;
}

void func(int id,int count,int* countstatus,char* chars){
    if(id<=count){
        int i=0;
        for(i=0;i<=1;i++)
        {
            countstatus[id]=i;
            func(id+1,count,countstatus,chars); //In Next   
        }
    }
    else{
        int showid;
        for(showid=1;showid<=count;showid++)
        {
        if(countstatus[showid])
        {   
           printf("%c",chars[showid-1]);
        }
        }
        printf("\n");
    }
}

答案 3 :(得分:0)

如果排列符合您的要求,那么您可以使用此递归解决方案。

$ cat perm.pl
#!/usr/bin/perl -w
use strict;

my @s =  @ARGV;

sub swap {
        my $i           = shift;
        my $j           = shift;
        my $tmp         = $s[$i];
        $s[$i]          = $s[$j];
        $s[$j]          = $tmp;
}

sub perm {
        my $n = shift;
        my $i = shift;

        if ( $i eq $n ) {
                print join ",", @s;
                print "\n";
        } else {
                for ( my $j=$i; $j<$n; $j++ ) {
                        swap( $i, $j );
                        perm( $n, $i+1);
                        swap( $i, $j );
                }
        }
}

perm( $#s+1, 0 );

$ ./perm.pl A B C
A,B,C
A,C,B
B,A,C
B,C,A
C,B,A
C,A,B

答案 4 :(得分:0)

而不是使用&#39;组合&#39; (来自下面的jaypal),使用&#39;子集&#39;获得powerset。

use Algorithm::Combinatorics 'subsets';

my @set = qw/ A C E /;

my @pwrset = subsets(\@set);

print "[@$_]\n" for @pwrset;

打印

[A C E]
[C E]
[A E]
[E]
[A C]
[C]
[A]
[]