【发布时间】:2015-03-30 00:38:31
【问题描述】:
我正在尝试使用foreach 循环遍历数组,然后使用嵌套的while 循环遍历文本文件的每一行,以查看数组元素是否与一行文本匹配;如果是这样,那么我将该行中的数据推送到一个新数组中以执行计算。
外部 foreach 循环似乎工作正常(基于每个数组元素的打印结果),但内部 while 循环没有循环(每次将相同的数据推入数组)。
有什么建议吗?
代码如下
#! /usr/bin/perl -T
use CGI qw(:cgi-lib :standard);
print "Content-type: text/html\n\n";
my $input = param('sequence');
my $meanexpfile = "final_expression_complete.txt";
open(FILE, $meanexpfile) or print "unable to open file";
my @meanmatches;
@regex = (split /\s/, $input);
foreach $regex (@regex) {
while (my $line = <FILE>) {
if ( $line =~ m/$regex\s(.+\n)/i ) {
push(@meanmatches, $1);
}
}
my $average = average(@meanmatches);
my $std_dev = std_dev($average, @meanmatches);
my $average_round = sprintf("%0.4f", $average);
my $stdev_round = sprintf("%0.4f", $std_dev);
my $coefficient_of_variation = $stdev_round / $average_round;
my $cv_round = sprintf("%0.4f", $coefficient_of_variation);
print font(
{ color => "blue" }, "<br><B>$regex average: $average_round
 Standard deviation: $stdev_round Coefficient of
variation(Cv): $cv_round</B>"
);
}
sub average {
my (@values) = @_;
my $count = scalar @values;
my $total = 0;
$total += $_ for @values;
return $count ? $total / $count : 0;
}
sub std_dev {
my ($average, @values) = @_;
my $count = scalar @values;
my $std_dev_sum = 0;
$std_dev_sum += ($_ - $average)**2 for @values;
return $count ? sqrt($std_dev_sum / $count) : 0;
}
【问题讨论】:
-
您计算averages is flawed 的方式,您的标准差将灾难性地失败。见Algorithms for calculating variance。当您使用它时,您可能需要无偏的标准差估计器。
-
另外,这个 CGI 脚本在哪里运行?在我看来,任何可以调用这个脚本的人都可以用它做一些有趣的事情。
-
我已经对您的 Perl 代码进行了布局,以便它更具可读性。您自己必须这样做,这样您就可以发现任何范围界定问题,并且只有在您希望帮助调试它时发布可读代码才是礼貌的。出于同样的原因,您必须始终将
use strict和use warnings放在您编写的每个Perl 程序的顶部。它们是发现代码问题的宝贵帮助,如果没有use strict,使用my声明任何内容都毫无意义。在这种情况下,use strict表明您未能声明@regex或$regex。 -
@SinanÜnür:你的博文很吸引人。我经常使用类似的东西来计算滚动统计,但没想到准确性会有所提高。 (我可能知道 Don Knuth 参与其中。)但我认为你夸大了“正确”做事的重要性。正如您自己所说,“现实世界的一个可取之处在于,给定变量不太可能包含具有如此极端范围的值”,我希望任何必须这样做的人都能明白这一点为这样一个不寻常的数据集编写需要特殊方法的数据。
-
@Borodin 最后你尝试了方差实验吗?那是一组彼此接近的数字。必须借助一些人为的例子一步一步地说明问题,但在现实生活中,你往往会做更多的总结。稳定计算很重要。