2

次の文字列を指定します。

<VACC-PROP-0><VACC-PROP-0><NUM><EXP-V-0><MIR-0><PREP>

私がやりたいことは、次のようにすべての可能な順序付けられた長さを列挙することです:

<VACC-PROP-0><VACC-PROP-0><NUM><EXP-V-0><MIR-0><PREP>
<VACC-PROP-0><VACC-PROP-0><NUM><EXP-V-0><MIR-0>
<VACC-PROP-0><VACC-PROP-0><NUM><EXP-V-0>
<VACC-PROP-0><VACC-PROP-0><NUM>
<VACC-PROP-0><VACC-PROP-0>
<VACC-PROP-0>

<VACC-PROP-0><NUM><EXP-V-0><MIR-0><PREP>
<NUM><EXP-V-0><MIR-0><PREP>
<EXP-V-0><MIR-0><PREP>
<MIR-0><PREP>
<PREP>

上記が手作業で行われているわけではありません。私が何かを見逃している可能性があります。しかし、アイデアは、すべての長さ (トークンの数) のすべての可能な順序付きトークンを識別することです。このコードを試してみましたが失敗しました。これを行う最善の方法は何ですか?

use Data::Dumper;
my $str = "<VACC-PROP-0><VACC-PROP-0><NUM><EXP-V-0><MIR-0><PREP>";

# Remove all the brackets
my @tokens = grep {!/^$/} split(/[><]/,$str);

# Print the combinations
foreach my $i (0 .. $#tokens) {

   print join(" ", @tokens[0..$i]),"\n";
}

ここで実行: https://eval.in/51023

4

1 に答える 1

4

任意の深さのネストされたループが必要です。

for my $use_token0 (0..1) {
   for my $use_token1 (0..1) {
      for my $use_token2 (0..1) {
         ...
      }
   }
}

そのためには、Algorithm::Loopsを使用しますNestedLoops

use Algorithm::Loops qw( NestedLoops );

my $str = "<VACC-PROP-0><VACC-PROP-0><NUM><EXP-V-0><MIR-0><PREP>";
my @tokens = split /(?<=>)(?=<)/, $str;

my $iter = NestedLoops([ ( [0,1] ) x @tokens ]);
while ( my @bools = $iter->() ) {
   say @tokens[ grep $bools[$_], 0..$#tokens ];
}

ただし、この場合、単に使用できます

my $str = "<VACC-PROP-0><VACC-PROP-0><NUM><EXP-V-0><MIR-0><PREP>";
my @tokens = split /(?<=>)(?=<)/, $str;

for my $i (0 .. (1<<@tokens)-1) {
   say @tokens[ grep $i & (1 << ($#tokens-$_)), 0..$#tokens ];
}
于 2013-09-27T03:22:30.117 に答える