我有一份我需要帮助的学校作业。现在,我知道你在想什么,但我的老师不在城里,也没有回复我的电子邮件,我的其他同学也不知道如何解决这个问题。一些指示和提示将不胜感激!
作业是这样的:
我们应该创建一个数组,用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" );
现在,正如我所说,我想自己解决这个问题,而且我花了整整两天的时间,但无论我做什么,似乎都无法解决。任何提示将非常感谢。附:应该提到的是,我们不应该使用任何模块/插件。
答案 0 :(得分:9)
我首先要解决几个风格点:
将您的潜点放在开头(或者如果您必须,最后)。将它放在代码中间是很麻烦的。
不要使用&
调用子程序 - 它的样式很糟糕,并且会产生一些奇怪的行为。在您的情况下:&average
实际上是在没有参数的情况下被调用的。一般来说这很糟糕,除非你明确知道为什么这样做,否则不要使用它。 (它确实有一些用途,但你知道什么时候看到它们 - 你不会在早期学习perl
)。
像这样的数组大写不是好形式,因为这就是模块/包的命名方式。如果可以的话,坚持使用小写变量。
你的for循环是一种C风格,但它可以更好地编写for ( 1..$random_number ) {
,因为你不需要迭代器。
您在shebang行上不需要-w
,因为您有use warnings
。 use warnings;
是更好的方法。
调用变量$random_number
并不是很有帮助 - 我们可以看到,因为它已为rand
分配了结果。称之为它的用途 - 如$number_of_elements
。
鉴于您只需要使用$random_number
一次,您可能不需要将其粘贴在变量中。你可以,如果你觉得它有助于可读性(这是一个品味问题 - 在良好的编程中,清晰可读是唯一真正重要的事情 - 鉴于今天的编译器状态,大多数内存/性能事情都是过早的优化。)
你的核心问题是:
my $ArrayAverage = @_;
将$ArrayAverage
设置为列表中的元素数。这将始终与$random_number
相同,因为这是您迭代的次数。
您在此处迭代元素,但实际上并未使用$total
。
for (@_) {
my $total += $_;
}
所以这里 - 你返回数组中的元素数除以数组中元素的数量。
return $ArrayAverage / $random_number;
但真正重要的是 - 这一切都不重要,因为你用&average
调用它并没有实际发送任何参数。所以你只是把零点放在零上面。
可能有用的是 - 标量上下文中的数组返回元素的数量,因此计算平均值就像:
my $sum;
$sum += $_ for @AllNumbers;
print( "\n\nThe average of those random numbers is: ", $sum / @AllNumbers, "\n\n" );
这会生成一个长小数 - 如果您需要格式化,可以使用printf
或sprintf
。
printf( "\n\nThe average of those random numbers is: %02.2f \n\n", $sum / @AllNumbers);
所以我会稍微改写一下:
#!/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);
答案 1 :(得分: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 / @_;
}
答案 2 :(得分:4)
你在寻求帮助之前尝试过自己的工作做得很好!
要调试代码,请尝试添加一些打印件以最小化您需要查找错误的区域。因此,在这种情况下,您可以在平均子级中添加print $random_number
,并且您会注意到它已设置正确。如果你打印$ ArrayAverage的元素,你会发现它没有值,这只是因为你需要将@AllNumbers数组传递给&amp; average sub,当你在最后一行的print中调用它时你的剧本。
所以解决方案是你只需要在被调用时将@AllNumbers数组传递给&amp; average():
print ("\n\nThe average of those random numbers is: ", &average(@AllNumbers), "\n\n");
这应该可以正常工作;)祝你好运!
答案 3 :(得分:4)
到目前为止,工作还不错!几乎可以。但是你没有调用你的平均功能
任何参数(&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");
调用函数时请省略&
。这是非常古老的风格。
喜欢大多数其他语言使用的风格:
my $result1 = some_function();
my $result2 = some_other_function($param1, $param2);
答案 4 :(得分:1)
(主要)问题是你没有参数调用你的sub! 试试这个:
average($_) foreach @AllNumbers;
my $count = 0;
my $total;
my $average;
sub average{
my $num = shift;
$count++; # count number of random numbers
$total += $num; # sum up
$average = $total/$count; # calculate average
return $average;
}
# Print the mean/average of the 20-30 numbers.
print ("\n\nThe average of those random numbers is: ", $average, "\n\n");
答案 5 :(得分:0)
有机会帮助你。
#! /usr/bin/perl -w
use warnings;
use strict;
# Declaring the scalar variables and arrays.
my @AllNumbers;
my $avgOfArray;
# 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 @array = @_; # save the array passed to this function
my $sum; # create a variable to hold the sum of the array's values
foreach (@array) { $sum += $_; } # add each element of the array
# to the sum
return $sum/@array; # divide sum by the number of elements in the
# array to find the mean
}
$avgOfArray = average(@AllNumbers);
# Print the mean/average of the 20-30 numbers.
print ("\n\nThe average of those random numbers is: ", $avgOfArray, "\n\n"); here
答案 6 :(得分:0)
您需要将参数传递给average
子例程:
#!/usr/bin/perl
sub average{
my $tot;
$tot += $_ for @_;
return sprintf '%.3f', $tot / @_;
}
my @num;
my $quantity = int(rand 11) + 20;
push @num, int(rand 100) + 1 for 1 .. $quantity;
print "Random numbers: \t@num\n";
print "Average: ", average(@num), "\n";