2010-09-12 1 views
3

Например, у меня есть массивКак получить все возможные комбинации соседних элементов в следующем порядке с помощью Perl?

my @arr = qw(0 1 2 3 4); 

Как получить следующие комбинации:

0 
01 
012 


1 
12 
123 
1234 
2 
23 
234 
3 
34 
4 

Если какой-либо, что название для такого рода комбинации (или перестановки)?

Спасибо, как всегда!

+2

Я считаю, что это можно было бы назвать найти все последовательные подпоследовательности массива. – cjm

+0

@cjm, спасибо за термин :) – Mike

ответ

6

Использование массива ломтиков:

#! /usr/bin/perl 

use warnings; 
use strict; 

my @arr = qw(0 1 2 3 4); 

my @result; 
for (my $i = 0; $i < @arr; $i++) { 
    for (my $j = $i; $j < @arr; $j++) { 
    push @result => [ @arr[$i .. $j] ]; 
    } 
} 

print @$_, "\n" for @result; 

Выход:

0 
01 
012 


1 
12 
123 
1234 
2 
23 
234 
3 
34 
4
+0

благодарит за код :) Это действительно помогает мне улучшить свои навыки Perl. BTW, когда мы создаем анонимный массив, используя массивы массивов @arr, как его содержимое, а затем нажимаем ссылку на @result, почему есть жирная запятая «=>» вместо обычной запятой «,»? Это конвенция? Я видел только жирную запятую, используемую в парах ключ/значение, и подпрограмму use constant. – Mike

+2

Использование '=>' вне пар ключ/значение - это стиль, которым пользуются некоторые люди. Я считаю, что это немного странно. – friedo

+3

@Mike In Perl 5 жирная запятая - это всего лишь причудливый вид оператора запятой (он действительно строит левые слова слева). Использование этого в случаях, отличных от конструкторов хэшей, иногда делает код более читаемым. Например, ['Moose'] (http://search.cpan.org/dist/Moose-1.12/lib/Moose.pm)' s имеет x => (isa => "Int", is => " rw ");' легче читать, чем 'имеет x", "isa", "Int", "is", "rw"; '; однако в этом случае я думаю, что это делает код более трудным для чтения. Это делает его похожим на '@ result', который будет помещен в анонимный массив. –

7

Лично я считаю "стиль C" для цикла, который gbacon использует часто усложняет код без необходимости. И, как правило, можно заменить его на «диапазон-стиль» для цикла, который проще отслеживать.

#!/usr/bin/perl 

use strict; 
use warnings; 

my @arr = qw(0 1 2 3 4); 

my @result; 
for my $i (0 .. $#arr) { 
    for my $j ($i .. $#arr) { 
    push @result => [ @arr[$i .. $j] ]; 
    } 
} 

print @$_, "\n" for @result; 
+0

спасибо за обмен кодом :) Я согласен, что этот «диапазон-стиль» для цикла более краток и читабельнее. Спасибо :) – Mike

1

Вот способ разделить проблему на более дискретные компоненты:

use strict; 
use warnings; 

sub consec_subseq_leading { 
    # (1, 2, 3) ==> ([1], [1, 2], [1, 2, 3]) 
    return map [ @_[0 .. $_] ], 0 .. $#_; 
} 

sub consec_subseq { 
    # (1, 2, 3) ==> (F(1, 2, 3), F(2, 3), F(3)) 
    # where F = consec_subseq_leading 
    my $j = $#_; 
    return map consec_subseq_leading(@_[$_ .. $j]), 0 .. $j; 
} 

my @cs = consec_subseq(0 .. 4); 
print "@$_\n" for @cs; 
+0

@FM, спасибо за обмен кодом, который имеет комментарии :) – Mike

Смежные вопросы