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

My 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);
      }
   }
}

そのサブルーチンを で呼び出してcombinations(8);、期待される結果を得ることができます。

..範囲演算子で、リストを生成します。アルファベット文字でも機能します。あなたがしたいでしょう'a' .. 'z', 0 .. 9

動作しますが@list、テスト用に小さいものを使用することをお勧めします。

これにより、すべての固定長文字列が生成されます。すべての文字列特定の長さにするには、次のようにします。

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

(幅優先)、または含む

print @list, "\n";

for深さ優先の -branch の-loopの直前else

脚注:

(*)いいえ、そうではありませんが、これは近いものです。関数型プログラミングでは、ループはまったく必要ありませ

于 2012-08-17T02:49:53.927 に答える