我没有使用相等的运算符来执行此操作,因为窗口大小的用户输入可能会有所不同。
print"Enter the window size";
my $p_win=<>;#window size can vary according to the user's requirement
chomp($p_win);
my $x=0;
my $y=$x+$p_win;
my $i=0;
my @count;
#initializing the value of the count for all the ranges as 0
while($x ne 1)
{
$count[$i]=0;
print "$x>= p >$y\t$count[$i]=\n";<>;
$x=$x+$p_win;
$y=$y+$p_win;
$i++;
}
$count[$i]=0;# count where the value of D is NA and E is 1
my $na=$i;
open(F1,"new.txt");
my $flag=0;
my (@a,@b);
while(<F1>)
{
if($flag == 0)
{
$flag++;#first line of the new.txt
}
else
{
chomp($_);
my @a=split(/\t/,$_);
$x=0;
$y=$x+$p_win;
for($i=0; $i<scalar(@count)-1; $i++)
{
if($a[3] eq 'NA')
{
$count[$na]++;
$i=scalar(@count);
}
else
{
if($x le $a[4] && $a[4]<$y)
{
$count[$i]++;
$i=scalar(@count);
}
my $t=scalar(@count)-2;
if($i== $t)
{
if($a[4] eq $y)
{
$count[$i]++;
}
}
}
$x=$x+$p_win;
$y=$y+$p_win;
}
}
}
new.txt
采用给定格式。将生成e
的频率分布:
a b c d e
1 2 4 5 0.1
1 2 3 4 0.2
1 2 4 5 0.9
1 2 3 4 0
1 2 4 NA 1
1 2 3 4 0.2
1 2 4 5 0.3
1 2 3 4 0.9
1 2 4 5 0.8
1 2 3 4 0.7
1 2 4 5 0.6
1 2 3 4 0.5
1 2 4 5 0.4
1 2 3 4 0.2
1 2 4 5 0.1
1 2 3 4 1
1 2 4 5 0.9
1 2 3 4 0.8
1 2 4 NA 1
1 2 3 4 0.4
1 2 4 5 0.5
1 2 3 4 0.2
1 2 4 5 0.3
1 2 3 4 0.1
输出结果为:
0 >= p > 0.1 1
0.1 >= p > 0.2 3
0.2 >= p > 0.3 6#count of 0.3-0.4 is also added here
0.3 >= p > 0.4 0
0.4 >= p > 0.5 2
0.5 >= p > 0.6 2
0.6 >= p > 0.7 1
0.7 >= p > 0.8 1
0.8 >= p > 0.9 2
0.9 >= p >= 1 4
NA 1 2
答案 0 :(得分:2)
首先,使用eq
,ne
和lt
等字符串比较器来比较数值总是一个坏主意。它使Perl将值转换为字符串并逐个比较字符,而不是直接比较数字。
此外,您永远不能比较浮点数的相等性,因为在英特尔浮点数中无法精确表示0.1之类的值。这尤其适用于值是一系列添加的结果,因为例如添加十个0.1的副本将导致每个值的十倍的错误
您可以允许任意误差范围,例如
if ( abs($x - $y) < 0.00001 ) { ... }
但那是笨拙和无意义的
到目前为止,使用这样的序列的最佳方法是将所有算法保持为整数格式。在我的回答中,我已经从使用窗口大小 $p_win
更改为窗口数 $num_win
,这始终是一个整数。然后,给定概率$i
的数组索引$p
仅为$i = int $p * $num_win
use strict;
use warnings 'all';
print "Enter the number of windows: ";
my $num_win = <>;
if ( $num_win and $num_win =~ /\S/ ) {
chomp $num_win;
}
else {
$num_win = 10; # Default to ten windows
}
printf "\nCalculating for %d Windows\n", $num_win;
my @count;
$_ = 0 for @count[0 .. $num_win];
open my $fh, '<', 'new.txt' or die $!;
while ( <$fh> ) {
next if $. == 1;
next unless /\S/;
my @fields = split;
my $i;
if ( $fields[3] eq 'NA' ) {
$i = $#count;
}
else {
$i = int $fields[4] * $num_win;
--$i if $i == $#count;
}
++$count[$i];
}
for my $i (0 .. $#count ) {
if ( $i < $#count ) {
printf "%.2f <= p < %.2f count %d\n", $i/$num_win, ($i+1)/$num_win, $count[$i];
}
else {
printf "%.2f (NA) count %d\n", $i/$num_win, $count[$i];
}
}
Enter the number of windows:
Calculating for 10 Windows
0.00 <= p < 0.10 count 1
0.10 <= p < 0.20 count 3
0.20 <= p < 0.30 count 4
0.30 <= p < 0.40 count 2
0.40 <= p < 0.50 count 2
0.50 <= p < 0.60 count 2
0.60 <= p < 0.70 count 1
0.70 <= p < 0.80 count 1
0.80 <= p < 0.90 count 2
0.90 <= p < 1.00 count 4
1.00 (NA) count 2