Perl - 创建强力列表

时间:2012-08-17 02:31:22

标签: perl

Perl的新手,我正在尝试定义一个字符子集,然后在文本文件中输出它们的所有可能组合(最多8个字符)。

我真的不喜欢'默认变量'或Perl的其他方面,所以我开始使用伪代码,希望有人可以帮我详细说明(我从例子中学到的最好)。

#Define output file
$filename=output.dat
$standard_output->$filename

#Define list
$list[]=regex/a..z 0..9/

#Cycle through iterations
foreach $letter1 in $list{
 print $list[$letter]
}

foreach $letter1 in $list{
 foreach $letter2 in $list{
  print $list[$letter1] $list[$letter2]
 }
}

...

foreach letter1 in list{
 foreach letter2 in list{
  foreach letter3 in list{
   foreach letter4 in list{
    foreach letter5 in list{
     foreach letter6 in list{
      foreach letter7 in list{
       foreach letter8 in list{
        print list[letter1] list[letter2] list[letter3] list[letter4] list[letter5] list[letter6] list[letter7] list[letter8]
       }
      }     
     }
    }
   }
  }
 }
}

你可以清楚地看到,我对此非常陌生。有人可以帮我解决Perl问题吗?

2 个答案:

答案 0 :(得分:4)

我的Set::CrossProduct模块使这很简单,并且没有堆栈或内存破坏递归就可以实现:

use v5.10;

use Set::CrossProduct;

my $min = 2;
my $max = 4;
my $set = [ qw( a b 1 2 ) ];

foreach my $length ( $min .. $max ) {
    say "Getting combinations of length $length";

    my $cross = Set::CrossProduct->new(
        [ ( $set ) x $length ]
        );

    while( my $tuple = $cross->get ) {
        say join '', @$tuple;
        }
    }

答案 1 :(得分:3)

功能编程*拯救!以下代码效率不高,但更清晰。

我们将定义一个以数字和列表作为参数的函数。数字表示我们要递归的次数,该列表包含来自外层的字母。

#!/usr/bin/perl
use strict; use warnings;
my @list = 'a' .. 'z'; # lowercase letters
sub combinations {
   my ($recursions, @letters) = @_; # unpack the arguments
   if ($recursions == 0) {
       print @letters, "\n"; # print the letters, append newline
   } else {
      # do a loop
      $recursions--; # reduce level
      for my $letter (@list) {
         combinations($recursions, @letters, $letter);
      }
   }
}

我们可以使用combinations(8);调用该子以获得预期结果。

..是范围运算符并生成一个列表。它也适用于字母字符。您需要'a' .. 'z', 0 .. 9

虽然您可能希望使用较小的@list进行测试,但它仍然有效。

这会生成所有固定长度的字符串。要使所有字符串达到给定长度,只需执行

combinations($length) foreach my $length (1 .. 8);

(广度优先),或包括

print @list, "\n";

for - 循环之前的else - 分支中,深度优先。

脚注:

(*)不,不是真的,但这很接近。功能编程根本不需要任何循环。