没有3个单词的Perl组合

问题描述 投票:0回答:2

我有一套15个单词,但不需要其中3个单词。我需要得到所有的组合。这些单词是排序的,不要混合它们。

我尝试从数组中删除,但脚本报告错误。

@words_orig = qw(Home Pronunciation Symbols Help About Mobile Apps Shop Dictionary API Privacy Policy Terms About2 Contact);
@words = (@words_orig);

for $w1 ( 0 .. $#words ) {
    delete @words[$w1];
    for $w2 ( 0 .. $#words ) {
        delete @words[$w2];
        for $w3 ( 0 .. $#words ) {
            delete @words[$w3];
            print join(' ', @words) . "\n";
            @words = (@words_orig);
        }
    }
}
perl
2个回答
1
投票

在这种情况下,使用单词的索引可能更好:

#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

my @words = qw( Home Pronunciation Symbols Help About Mobile Apps Shop
                Dictionary API Privacy Policy Terms About Contact );
for my $i (0 .. $#words) {
    for my $j ($i + 1 .. $#words) {
        for my $k ($j + 1 .. $#words) {
            say join ' ', @words[ grep $_ != $i && $_ != $j && $_ != $k,
                                  0 .. $#words ];
        }
    }
}

请注意,“About”被提及两次,因此通过字符串比较比较单词将返回不同的列表:

#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

my @words = qw( Home Pronunciation Symbols Help About Mobile Apps Shop
                Dictionary API Privacy Policy Terms About Contact );

for my $i (@words) {
    for my $j (@words) {
        next if $i le $j;

        for my $k (@words) {
            next if $j le $k || $i le $k;

            say join ' ', grep $_ ne $i && $_ ne $j && $_ ne $k, @words;
        }
    }
}

1
投票

应该有C(15,15-3)=(15 * 14 * 13)/(3 * 2 * 1)= 455溶液。

可以使用以下方法找到:

for my $i00 (0      .. $#words) {
for my $i01 ($i00+1 .. $#words) {
for my $i02 ($i01+1 .. $#words) {
for my $i03 ($i02+1 .. $#words) {
for my $i04 ($i03+1 .. $#words) {
for my $i05 ($i04+1 .. $#words) {
for my $i06 ($i05+1 .. $#words) {
for my $i07 ($i06+1 .. $#words) {
for my $i08 ($i07+1 .. $#words) {
for my $i09 ($i08+1 .. $#words) {
for my $i10 ($i09+1 .. $#words) {
for my $i11 ($i10+1 .. $#words) {
   say "@words[$i00, $i01, $i02, $i03, $i04, $i05,
               $i06, $i07, $i08, $i09, $i10, $i11]";
}}}}}}}}}}}}

以上也可以写成如下:

use Algorithm::Loops qw( NestedLoops );

my $iter = NestedLoops([
   [ 0..$#words ],
   ( sub { [ $_+1..$#words ] } ) x ( @words - 3 - 1 ),
]);

while ( my @indexes = $iter->() ) {
   say "@words[@indexes]";
}

请注意,所提供的解决方案将重复的单词视为不同的单词。这应该没问题,因为OP表明存在重复的单词是错误的。

© www.soinside.com 2019 - 2024. All rights reserved.