0

1 つ以上の配列の平均を取るサブルーチンに取り組んでいます。モジュールを使用せずにこれを行いたいと思います。

use strict;
use warnings;

use List::Util 'sum';

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

# the average of these four arrays is (1,2) since
# (0+1+2+1)/4 = 1 and (2+3+2+1)/4 = 2    

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

my @avg;
# this is the way to do it using the module
for my $i (0..$#w) {
    $avg[$i] =  sum(map $_->[$i], @arrays) / @arrays;
}
print "@avg\n";

# my way of doing it without module
@avg;
for my $i (0..$#w) {
    $avg[$i] = prod_sum(map $_->[$i], \@arrays) / @arrays;
}

print "@avg\n";


# subroutines
sub prod_sum{
    my $o = $_[0];
    my $arr_ref = $_[1];
    my $array_ref;

    foreach my $row (@$arr_ref){
        foreach my $cell (@$row) {
            push(@{ $array_ref }, $_);
        }
    }

    my $sum = $o + the_sum($array_ref);
    return $sum;
}

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

出力

1 2
[pair of really random big numbers]

最初の出力は正しいです。すべての配列の平均が表示されます。2 番目の出力は完全に間違っています。モジュールを使用せずにこれを行うにはどうすればよいですか?

4

2 に答える 2

1

sum に 2 つの変数が渡されていると思いますが、そうではありません。配列が渡されるだけです。prod_sum を変更して、配列のみを期待するようにします\@arrays(prod_sum の呼び出しを just に置き換えます@arrays)。または、これを使用できます:

sub sum {
  return 0 if $#_ < 0;
  my $head = shift;
  return $head + sum(@_);
}

上記は、配列を合計する再帰的なサブルーチンです。

注: 配列に 100 を超える要素がある場合use warnings、深い再帰の警告が発せられます。そのトピックの詳細については、ここを参照してください

于 2013-04-05T20:43:56.800 に答える
1

私はこの解決策を提案します:

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)
于 2013-04-05T20:53:25.923 に答える