鉴于此字符串:
<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";
}
答案 0 :(得分: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 ];
}