数组的循环移位

时间:2015-04-07 12:11:46

标签: perl

如何在Perl中移动圆形数组?

例如,

use strict;
use warnings;
use Data::Dump;

my $a = [[1], [3], [2], [4]];
my $shift_index = 2;
circ_shift( $a, $shift_index );
dd $a;

应该给出输出:

[[2], [4], [1], [3]]

所以$shift_index是向左移动的位置数。

4 个答案:

答案 0 :(得分:9)

my @a = qw(1 2 3 4);
my $i = 2;
push(@a, splice(@a, 0, $i));

答案 1 :(得分:6)

要在数组上移动元素,请使用shift/unshiftpush/pop

use strict;
use warnings;
use Data::Dumper;

my @list = ( "one", "two", "three", "four" );

push ( @list, shift @list);
print Dumper \@list;

unshift ( @list, pop @list );
print Dumper \@list;

因此你的“转变”功能看起来有点像:

sub cycle_list {
    my ( $list_ref, $number_shift ) = @_;
    for ( 1 .. $number_shift ) {
        push( @$list_ref, shift @$list_ref );
    }
}

cycle_list( \@list, 2 );
print Dumper \@list;

通过引用传递列表允许您修改引用的列表。如果您愿意,可以传入一堆值并从子中返回移位列表。

答案 2 :(得分:5)

作为Denis Ibaev has intimatedcirc_shift最好使用splice来实现,pop可以同时for多个元素并且不需要use strict; use warnings; use Data::Dump; my $a = [[1], [3], [2], [4]]; my $shift_index = 1; circ_shift( $a, $shift_index ); dd $a; sub circ_shift { my ($list, $n) = @_; push @$list, splice @$list, 0, $n; } }循环。

看起来像这样

[[3], [2], [4], [1]]

<强>输出

{{1}}

答案 3 :(得分:2)

如果你想要的只是按旋转的顺序浏览数组的元素,即使修改了pushpopsplice,也不需要混淆对于我们大多数人来说,阵列到位或创建新阵列是最直观的方法。

但是,您可以创建一个迭代器,它将通过应用偏移量并使用数组的大小剪切它来以旋转的顺序遍历数组:

#!/usr/bin/env perl

use strict;
use warnings;

my @x = ('a' .. 'z');

for my $d (3, 5, 43) {
    my $it = rotated_it(\@x, $d);
    print "@x[ map $it->($_), 1, 3, 5, 7, 11, 13 ]\n";
}

sub rotated_it {
    my $k = @{ $_[0] };
    my $c = $_[1] - 1;
    sub { ($_[0] + $c) % $k };
}

如果底层数组很大并且您需要的只是旋转数组中的一些元素,或者您希望能够一次遍历一个元素而不创建额外的数组等,那么这可能特别有用。< / p>

输出:

d f h j n p
f h j l p r
r t v x b d