0

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 吗?

4

2 回答 2

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;
        }
    }
于 2012-08-17T04:17:33.407 回答
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);
      }
   }
}

我们可以调用那个 subcombinations(8);来获得预期的结果。

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

它可以工作,尽管您可能希望使用较小@list的进行测试。

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

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

(广度优先),或包括

print @list, "\n";

就在深度优先的 -branch 中的for-loop之前。else

脚注:

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

于 2012-08-17T02:49:53.927 回答