如何在Perl中按元素求和数组?

时间:2009-12-08 09:54:33

标签: arrays perl sum elementwise-operations

我有两个数组:

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

我想将两个数组的项目相加以获得新的数组,如

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

我可以不循环播放数组吗?

9 个答案:

答案 0 :(得分:29)

for Perl 5:

use List::MoreUtils 'pairwise';
@sum = pairwise { $a + $b } @arr1, @arr2;

答案 1 :(得分: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有更多例子。

答案 2 :(得分:8)

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

如果你担心在非常大的数组上进行循环,那么最好还是考虑其他方法来保持最新的总和。

答案 3 :(得分: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";
}

答案 4 :(得分: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;

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

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

答案 5 :(得分:1)

如果你真的害怕循环,那么你可以二进制切割数组,求和,然后递归地重新组合生成的数组。没有循环,作为奖励,你可以学习快速傅立叶变换推导的部分工作原理。

答案 6 :(得分:1)

来自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

答案 7 :(得分:0)

为了避免(显式)循环,这里有一个使用递归的解决方案&#34;而不是#34;:

#!/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道歉/赞扬这个想法。

答案 8 :(得分:0)

我不确定你计划用这笔款项做什么,但是你打算做更多的矢量类型的东西,那么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);