任何人都可以帮我解决这个问题吗?我正在尝试编写一个占用许多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;
}
我的尝试很接近,但不起作用。我想在不使用模块的情况下这样做。
答案 0 :(得分: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)
答案 1 :(得分: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";
答案 2 :(得分: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]
指定特定位置。
答案 3 :(得分: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
答案 4 :(得分:1)
map
不会返回数组。 docs
更改
@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;
}