我有几对数字,想要检查第一个是否属于给定的间隔。如果是这样,我想为该间隔增加两个计数器中的一个,具体取决于该对的第二个数字是高于还是低于第一个。
间隔很简单,看起来像1-10,11-20,21-30等。数字对看起来像(5,15),(24,13)等。但我有几千个。确切的输入格式并不重要。
期望的结果如下所示
1-10: higher=1, lower=0
11-20: higher=0,lower=0
21-30: higher=0,lower=1
我的想法是创建一个以间隔start作为键的哈希值,并将两个计数器存储在值中。
for(my $i = $start;$i<=$end;$i = ($i+$intervalsize)){
my $counter1 = 0;
my $counter2 = 0;
@{$hash{$i}} = ($counter1,$counter2);
但现在我不知道如何比较数字和键以及如何处理计数器。 谢谢你的帮助!
答案 0 :(得分:0)
如果要为每个间隔保留计数器,我们可以将它们记录在所选的数据结构中。例如,在散列中为每个时间间隔存储计数器,其中键是间隔索引,而低 - 高计数器在两元素的重组中作为其值。
use warnings 'all';
use strict;
my @intervals = ( [1,10], [11,20], [21,30] );
my @pairs = ( [5,15], [24, 13] );
my %counter = map { $_ => [0,0] } (0..$#intervals); # initialize
foreach my $i (0..$#intervals)
{
foreach my $pair (@pairs)
{
my ($beg, $end) = @{$intervals[$i]};
my ($pl, $pr) = @$pair;
if ($pl >= $beg and $pl <= $end)
{
if ($pr > $pl) { ++$counter{$i}[1] }
else { ++$counter{$i}[0] }
}
}
}
print "$_ => @{$counter{$_}}\n" for sort keys %counter;
这仍然是基本的,以便更容易调整。首先,由于哈希使用@intervals
数组的索引,因此它本身可能是一个数组(带有arrayrefs)。另一种可能性是使用带有low
和high
等键的哈希值作为计数器而不是双元素数组。
为了使用间隔开始作为关键
my %counter = map { $_->[0] => [0,0] } @intervals; # initialize
for my $inter (@intervals) {
for my $pair (@pairs) {
my ($beg, $end) = @$inter;
my ($pl, $pr) = @$pair;
if ($pl >= $beg and $pr <= $end)
{
if ($pr > $pl) { ++$counter{$beg}[1] }
else { ++$counter{$end}[0] }
}
}
}
printf("%3d => @{$counter{$_}}\n", $_) for sort keys %counter;
答案 1 :(得分:0)
这样的事可能吗?
#!/usr/bin/env perl
use strict;
use warnings;
use List::MoreUtils qw( first_index );
sub interval_to_key { sprintf '(%d,%d)', @{ $_[0] } }
my @intervals = (
[ 1, 10 ],
[ 11, 20 ],
[ 21, 30 ],
);
my @upper_bounds = map $_->[0], @intervals;
my @pairs = (
[ 5, 15 ],
[ 24, 13 ],
);
my @keys = qw( ascending descending );
my %counts;
for my $interval ( @intervals ) {
@{ $counts{ interval_to_key($interval) } }{ @keys } = (0) x @keys;
}
for my $pair ( @pairs ) {
my $is_ascending = ($pair->[0] <= $pair->[1]);
my $i = first_index { $pair->[0] <= $_ } @upper_bounds;
++ $counts{ interval_to_key( $intervals[$i]) }{ $keys[1 - $is_ascending] };
}
use Data::Dumper;
print Dumper \%counts;