-2

谁能帮我解决这个问题?我正在尝试编写一个脚本,该脚本需要许多 N 大小的数组的总和。(1,2)在下面的示例中,数组的平均值为(0+1+2+1)/4 = 1(2+3+2+1)/4 = 2。目前,下面的代码仅适用于大小为 2 的数组。我将如何处理大小为 100 的数组以使 @results 的长度为 100?我想我需要一个柜台,对吧?

use strict;
use warnings;

my @w = (0, 2);
my @x = (1, 3);
my @y = (2, 2);
my @z = (1, 1);

my @arrays = \(@w, @x, @y, @z);

my ($x, $y) = (0, 0);
foreach my $arr(@arrays) {
    $x += $arr->[0];
    $y += $arr->[1];
}

my @result = ( $x / @arrays,  $y / @arrays);

print "@result\n";  # <---- prints 1 2

#######
# my attempt
my @avg;
for my $i(0..$w) {
    # I'm guessing the result 'map...' returns is an array
    @avg[$i] = sum(\(map $_->[$i], @arrays)) / @arrays;    
}    

# sum the elements in an array and return its value
sub sum{
# takes 1 param: an arrey_ref
    my $sum = 0;
    for ( @{$_[0]} ) {
    $sum += $_;
    }
    return $sum;
}

我的尝试很接近,但它不起作用。我想在不使用模块的情况下做到这一点。

4

5 回答 5

2

这是我的解决方案:

use strict;
use warnings;

my $SIZE = 3;
my @w = (0, 2, 3);
my @x = (1, 3, 4);
my @y = (2, 2, 6);
my @z = (1, 1, 3);

my @arrays = \(@w, @x, @y, @z);

my @result = ();
foreach my $arr(@arrays) {
    for(my $i=0; $i<$SIZE; $i++) {
        $result[$i] += $arr->[$i];
    }
}

@result = map { $_ / @arrays } @result;

print "(@result)", "\n";  # <---- prints (1 2 4)
于 2013-04-05T23:08:28.087 回答
1

map不返回数组。文档

改变

@avg[$i] = sum(\(map $_->[$i], @arrays)) /@arrays;

$avg[$i] = sum( map $_->[$i], @{$arrays[$i]} ) / @{$arrays[$i]};

和改变

sub sum{
    my $sum = 0;
    for ( @{$_[0]} ) {
    $sum += $_;
    }
    return $sum;
}

sub sum {
    my $sum;
    $sum += $_ for @_;
    return $sum;
}
于 2013-04-06T12:38:55.553 回答
1

List::Util模块对于此类问题非常有用。再加上一个简单的average子程序,它使一切变得非常简单。

use strict;
use warnings;

use List::Util 'sum';
sub average { sum(@_) / @_ }

my @w = (0, 2);
my @x = (1, 3);
my @y = (2, 2);
my @z = (1, 1);

my @arrays = \(@w, @x, @y, @z);

my @results = map {
  my $i = $_;
  average(map $_->[$i], @arrays);
} 0 .. $#{$arrays[0]};

print "@results\n";

输出

1 2
于 2013-04-06T01:26:17.027 回答
1

以一种简单的方式进行,如下所示:

#!/usr/bin/env perl

use strict;
use warnings;

my @w = (1, 2, 3, 4);
my @x = (1, 2, 3, 4);
my @y = (1, 2, 3, 4);
my @z = (1, 2, 3, 4);

my @arrays = \(@w, @x, @y, @z);

my @sums;
foreach my $arr(@arrays) {
    for( my $i = 0; $i <= $#w; $i++, $j++ )
    {
    $sums[$j] += $arr->[$i];
    }
}

my @avg = map { $_ / @arrays } @sums;

foreach( @avg )
{
    print "$_ ";
}

print "\n";
于 2013-04-05T23:16:54.503 回答
1

是的,它非常接近。以下是对问题代码的更正:

my @avg;
for my $i (0..$#w) {
    my @transposed = map {$_->[$i]} @arrays;
    $avg[$i] = sum(\@transposed) / @transposed;
    # or in one line: $avg[$i] = sum( [map {$_->[$i]} @arrays] ) / @arrays;
}

(我假设数组@w@x和都是相同的大小。@y@z

请注意,这@avg[$i]是一个数组切片。你想$avg[$i]指定一个特定的位置。

于 2013-04-05T23:18:08.943 回答