Perl从随机填充的数组计算平均值

tob*_*os1 10 arrays perl

我有一份我需要帮助的学校作业.现在,我知道你在想什么,但我的老师不在城里,也没有回复我的电子邮件,我的其他同学也不知道如何解决这个问题.一些指示和提示将不胜感激!

作业是这样的:

我们应该创建一个数组,用1-100的20到30个随机整数填充它.然后,在子程序的帮助下,我们应该计算这些数字的平均值.

当我调用子程序时会出现问题,这给了我0或"非法除0"错误.我现在的代码是这样的:

#! /usr/bin/perl -w

use warnings;
use strict;

# Declaring the scalar variables and arrays.
my @AllNumbers;

# Create random data set of between 20 to 30 measures used for the 100 random intigers.
my $random_number = int( rand( 31 - 20 ) ) + 20;

# Create random data set of 100 intigers.
for ( my $i = 0 ; $i <= $random_number ; $i++ ) {
    $AllNumbers[$i] = int( rand( 100 - 1 ) );
}

# Print the 20 to 30 random numbers (range 1 - 100).
print("Your random numbers are: \n@AllNumbers");

sub average {
    my $ArrayAverage = @_;
    for (@_) {
        my $total += $_;
    }
    return $ArrayAverage / $random_number;
} ## end sub average

# Print the mean/average of the 20-30 numbers.
print( "\n\nThe average of those random numbers is: ", &average, "\n\n" );
Run Code Online (Sandbox Code Playgroud)

现在,正如我所说的那样,我想自己解决这个问题,而且我花了整整两天的时间,但无论我做什么,似乎都无法解决.任何提示将非常感谢.PS应该提到的是,我们不应该使用任何模块/插件.

Sob*_*que 9

我首先要解决几个风格点:

  • 把你的潜艇放在开头(或者你必须在最后).将它放在代码中间是混乱的.

  • 不要调用子程序&- 它的样式很糟糕,并且会产生一些奇怪的行为.在你的情况下:&average有效地被调用没有参数.一般来说这很糟糕,除非你明确知道为什么这样做,否则不要使用它.(它确实有一些用途,但你会知道什么时候看到它们 - 你不会在早期学习中perl).

  • 像这样的数组的大写不是好的形式,因为这就是模块/包的命名方式.如果可以的话,坚持使用小写变量.

  • 你的for循环是一种C风格,但它可以更好地编写,for ( 1..$random_number ) {因为你不需要迭代器.

  • 你不需要-w在shebang线上,因为你有use warnings.use warnings;这是更好的方式.

  • 调用你的变量$random_number不是很有用 - 我们可以看到,因为它已经为其分配了结果rand.称之为它的用途 - 就像$number_of_elements.

  • 鉴于你只需要使用$random_number一次,你可能不需要将它粘在一个变量中.你可以,如果你觉得它有助于可读性(这是一个品味问题 - 在良好的编程中,清晰可读是唯一真正重要的事情 - 鉴于今天的编译器状态,大多数内存/性能事情都是过早的优化.)

你的核心问题是:

my $ArrayAverage = @_;
Run Code Online (Sandbox Code Playgroud)

这设置$ArrayAverage为列表中的元素数量.这将始终相同$random_number,因为这是您迭代的次数.

你在这里迭代元素,但实际上并没有使用$total.

for (@_) {
    my $total += $_;
}
Run Code Online (Sandbox Code Playgroud)

所以这里 - 你返回的数组中的元素数除以数组中的元素数.

return $ArrayAverage / $random_number;
Run Code Online (Sandbox Code Playgroud)

但真正重要的是 - 这一切都不重要,因为你正在调用它&average实际上没有发送任何参数.所以你只是把零点放在零上面.

知道它可能很有用 - 标量上下文中的数组返回元素的数量,因此计算平均值就像这样简单:

my $sum; 
$sum += $_ for @AllNumbers; 
print( "\n\nThe average of those random numbers is: ", $sum / @AllNumbers, "\n\n" );
Run Code Online (Sandbox Code Playgroud)

这将产生一个长小数 - 如果你需要格式化它,你可以使用printfsprintf.

printf( "\n\nThe average of those random numbers is: %02.2f \n\n", $sum / @AllNumbers);
Run Code Online (Sandbox Code Playgroud)

所以我会稍微改写它:

#!/usr/bin/perl

use warnings;
use strict;

# Declaring the scalar variables and arrays.
my @all_numbers;


#repeat 20 + random 11 times - so 20-30
for ( 1 .. 20 + int rand 11 ) { 
    push ( @all_numbers, int rand 99 );
}

# Print the 20 to 30 random numbers (range 1 - 100).
print("Your random numbers are: \n@all_numbers\n");

#calculate sum of elements
my $sum; 
$sum += $_ for @all_numbers;

print "Sum: $sum count: ", scalar @all_numbers, "\n"; 

# Print the mean/average of the 20-30 numbers.
printf( "\n\nThe average of those random numbers is: %02.2f \n\n", $sum / @all_numbers);
Run Code Online (Sandbox Code Playgroud)

  • 好吧,至少你得到了重要的一点 - 如何自己尝试,并在Stack Overflow上提出一个不错的问题.这本身就是一种有价值的编程技术!:) (5认同)

Dav*_*oss 6

用惯用的Perl写它会给你这样的东西:

#!/usr/bin/perl

use warnings;
use strict;

my @numbers;

my $how_many = int(rand 11) + 20;

push @numbers, int(rand 100) + 1 for 1 .. $how_many;

print "Your random numbers are: \n@numbers\n";
print "The mean of those numbers is: ", average(@numbers), "\n";

sub average{
  my $total;
  $total += $_ for @_;
  return sprintf '%.2f', $total / @_;
}
Run Code Online (Sandbox Code Playgroud)


Per*_*uck 5

干得好,到目前为止!几乎没问题。但是您调用的是没有任何参数的平均函数 ( &average)。像这样尝试:

sub average{
    my @Array_To_Average = @_; # this is now a local copy of the global @AllNumbers
    my $total = 0;
    for (@Array_To_Average) # iterate over the local copy ...
    { 
        $total += $_; # ...and sum up
    }
    return $total / $random_number;

    # instead of $random_number you could also use
    # scalar(@Array_To_Average). That's the number of items
    # in the array, i.e.
    #   return $total / scalar(@Array_To_Average);
}

print ("\n\nThe average of those random numbers is: ", average(@AllNumbers), "\n\n");
Run Code Online (Sandbox Code Playgroud)

&调用函数时请省略。这是非常古老的风格。更喜欢大多数其他语言中使用的样式:

my $result1 = some_function();
my $result2 = some_other_function($param1, $param2);
Run Code Online (Sandbox Code Playgroud)

  • 如果您需要强制使用标量上下文,则需要 `scalar`。尤其是在打印时。(`print` 默认为列表上下文)。如果您正在执行数字运算(例如`$num / @array`),那么标量上下文已经就位,因此您不需要它。 (2认同)