2015-04-07 66 views
1

如何在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是向左移动的位置的数目。

回答

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; 

传递引用列表,您可以修改所引用的名单。如果您愿意,您可以传入一堆值并从子项返回移位的列表。

+0

谢谢!完美的作品:) –

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

作为丹尼斯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]] 
2

如果你想要的是去通过阵列的旋转顺序的元素,你不需要乱与push,popsplice即使修改阵列或创建一个新的是我们大多数人最直观的方法。

可以,然而,创建一个迭代器,它通过施加偏移和使用该阵列的尺寸裁剪它遍历在旋转顺序阵列:

#!/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 }; 
} 

这可能是特别有用的,如果底层阵列大,所有你需要的是从旋转阵列中的几个要素,或者如果你希望能够在一个时间数组一个元素遍历不会产生额外的阵列等

输出:

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