所以我有一个数组(比如说@array),其排序值介于0和1之间,还有一个散列(比如%hash),其键被排序,并且是0到1之间的数字。每个键的值在hash是0.现在,我需要查看@array的每个元素,找到%hash中的键,它立即小于它,并将相应的值递增1。也就是说,键用作间隔的下限
如果说
$array = (0.15,0.33,0.67,0.87)
and %hash = ("0.25", 0, "0.50", 0, "0.75", 0)
我接受$array[1] = 0.33
然后,我需要能够确定$ array [1]大于0.25但是小于0.5,因此,将“0.25”的值递增1给我一个更新的散列%hash =(“0.25 “,1,”0.50“,0,”0.75“,0)。
我希望这是有道理的!提前谢谢!!!
答案 0 :(得分:4)
哈希不按排序顺序存储密钥。您必须重新考虑解决问题的方法。
答案 1 :(得分:4)
您正在为间隔或范围构建频率分布。 CPAN有模块可以做到这一点。如果您可以重新表述您的问题以同意这些模块如何理解频率分布,您将能够节省一些麻烦并获得对您的项目可能有用的其他统计工具的访问权限。一个例子:
use Statistics::Descriptive;
my @data = (0.15, 0.33, 0.67, 0.87);
my @bins = (0.25, 0.50, 0.75, 1.00);
my $stat = Statistics::Descriptive::Full->new();
$stat->add_data(@data);
my $freq = $stat->frequency_distribution_ref(\@bins);
$freq
中的分布将是这样的哈希引用:
$freq = {
'0.25' => 1
'0.5' => 1, # N of items x, such that PREVIOUS_BIN_VAL < x <= .50
'0.75' => 1,
'1' => 1,
};
如果您无法修改问题,则需要自行计算发布,但您可以从Statistics::Descriptive获取重要提示。特别是,您可以获得bin值的有序列表。这是一个例子:
my @data = (0.15, 0.33, 0.67, 0.87);
my @bins = (0.25, 0.50, 0.75); # Include 0.0 if you want 0.15 to be tallied.
my %freq = map {$_ => 0} @bins;
for my $d (@data){
for my $b (reverse @bins){
do { $freq{$b} ++; last } if $d >= $b;
}
}
答案 2 :(得分:0)
据我了解,您希望跟踪$array
中的项目数量少于%hash
因此,对于散列中的每个键值,您只需从数组中检索小于列表中键的所有项,并获取其计数。您可以将grep用于此
use strict;
use warnings;
use Data::Dumper;
my $array = [qw (0.15 0.33 0.67 0.87 1.5) ] ;
my %hash = (0.25 => 0, 0.50 => 0, 0.75 => 0, 0.05 => 0);
for my $k (keys %hash) {
my @filtered = grep { $_ < $k } @$array;
$hash{$k} = @filtered;
#$hash{$k} = @filtered ? 1 : 0 # if you just want a flag
}
print Dumper(\%hash);
答案 3 :(得分:0)
如果您的哈希键均匀分布,就像您的示例中一样,每个哈希键都可以通过像$biggestSmaller = int(i*4)/4
这样的简单公式计算。如果没有,你需要一个辅助索引,如@keys = sort keys %hash
- 它也可能是一个二叉树,但这很简单,一个简单的列表应该做(如果速度不重要,你甚至可能是如此懒惰自下而上搜索,而不是实现二进制搜索。)