2013-09-27 25 views
2

鑑於此字符串:枚舉下令所有可能的長度標記在Perl

<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

你想任意深度的嵌套循環。

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

對於這一點,你用Algorithm::LoopsNestedLoops

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 ]; 
} 
+0

始終是個天才,我從下午就知道了。順便說一句,給定一個像1234(每個數字代表一個標記)的字符串,有沒有一種方法來按順序枚舉,但允許在它們之間丟失標記。例如1234,123,12,13,14,23,24,34,234等。 – neversaint

+1

我沒有在那裏看到訂單 – ikegami

+0

13是按原始字符串排列但不是31. – neversaint