14

我有两个数组:

@arr1 = ( 1, 0, 0, 0, 1 );
@arr2 = ( 1, 1, 0, 1, 1 );

我想对两个数组的项目求和以获得新的

( 2, 1, 0, 1, 2 );

我可以在不循环数组的情况下做到这一点吗?

4

9 回答 9

31

对于 Perl 5:

use List::MoreUtils 'pairwise';
@sum = pairwise { $a + $b } @arr1, @arr2;
于 2009-12-08T10:05:29.173 回答
8

如果您使用的是 Perl 6:

@a = (1 0 0 0 1) <<+>> (1 1 0 1 1)  #NB: the arrays need to be the same size

Perl 6 Advent Calendar有更多示例。

于 2009-12-08T10:01:15.437 回答
8

从根本上说,不,如果没有“遍历数组”就无法做到这一点,因为您需要访问两个数组的每个元素才能对它们求和。到目前为止,这两个答案都只是将循环隐藏在抽象层下,但它仍然存在。

如果您担心对非常大的数组进行循环,最好考虑使用其他方法来使总和保持最新。

于 2009-12-08T10:18:56.170 回答
7

循环数组有什么问题?这就是基本面。

@arr1 = ( 1, 0, 0, 0, 1 );
@arr2 = ( 1, 1, 0, 1, 1 );
for ($i=0;$i<scalar @arr1;$i++){
    print $arr[$i] + $arr2[$i] ."\n";
}
于 2009-12-08T11:46:33.700 回答
6

您已经看到了 C 风格的 for 循环,并且pairwise. 这是一个惯用的 Perl for 循环和map

my @arr1 = ( 1, 0, 0, 0, 1 );
my @arr2 = ( 1, 1, 0, 1, 1 );

my @for_loop;
for my $i ( 0..$#arr1 ) { 
    push @for_loop, $arr1[$i] + $arr2[$i];
}

my @map_array = map { $arr1[$_] + $arr2[$_] } 0..$#arr1;

我喜欢map并且pairwise最好。我不确定我在这两个选项之间是否有偏好。 pairwise为您处理一些无聊的管道细节,但它不是内置的map. 另一方面,地图解决方案非常惯用,对于兼职人员来说可能是不透明的。

因此,这两种方法都没有真正的胜利。IMO,两者pairwisemap很好。

于 2009-12-08T17:22:09.077 回答
2

来自http://www.perlmonks.org/?node_id=122393

@a = qw(1 2 3 4);
@b = qw(1 2 3 4);
@c = (); 

@c = map { $a[$_] + $b[$_] } ( 0 .. (@a > @b ? $#a : $#b) );

或者:

$c[@c] = $a[@c] + $b[@c] while defined $a[@c] or defined $b[@c];

或者:

$c[$_] = $a[$_] + $b[$_] for 0 .. (@a > @b ? $#a : $#b);

或者(在 Perl 6 中):

@c = @a ^+ @b
于 2015-01-27T21:08:55.650 回答
1

如果你真的害怕循环,那么你可以对数组进行二进制切分,对这些对求和,然后递归地重新组装得到的数组。那里没有循环,作为奖励,您可以了解快速傅立叶变换推导的部分工作原理。

于 2009-12-10T13:56:48.927 回答
0

为了避免(显式)循环,这是一个使用递归“代替”的解决方案:

#!/usr/bin/perl

use v5.20;

my @arr1 = ( 1, 0, 0, 0, 1 );
my @arr2 = ( 1, 1, 0, 1, 1 );

my @result=non_looping_pairwise_sum([ @arr1 ], [ @arr2 ]); # pass in copies, so the originals are not modified
say "@result";

sub non_looping_pairwise_sum { # only handles lists that have the same length
    my ($a1, $a2)=@_;

    return () if (scalar(@$a1)==0 and scalar(@$a2)==0);

    my $e1=shift @$a1;
    my $e2=shift @$a2;

    return ($e1+$e2, non_looping_pairwise_sum($a1, $a2));
}

输出:

2 1 0 1 2

请注意,我认为这use v5.20意味着您不必写use strict; use warnings

向@parm 表示歉意/感谢这个想法。

于 2015-01-27T21:25:39.823 回答
0

我不确定你打算如何处理总和,但你打算做更多向量-y 类型的东西,那么 Math::Matrix 可能是一个不错的选择。

use Math::Matrix;

my $foo = Math::Matrix->new([ 1, 0, 0, 0, 1 ]);
my $bar = Math::Matrix->new([ 1, 1, 0, 1, 1 ]);
my $sum = $foo->add($bar);
于 2015-01-27T23:10:50.560 回答