[英]Perl- Reading sorted array elements into a hash with sorted keys
所以我有一个数组(比如@array),其排序值介于0和1之间,还有一个散列(比如%hash),其键被排序,并且是0到1之间的数字。散列中每个键的值为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)。
我希望这是有道理的! 提前致谢!!!
哈希不按排序顺序存储密钥。 您必须重新考虑解决问题的方法。
您正在为间隔或范围构建频率分布。 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;
}
}
据我所知,你想跟踪$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);
如果你的哈希键是均匀间隔的,就像在你的例子中一样,每个哈希键都可以通过一个简单的公式来计算,比如$biggestSmaller = int(i*4)/4
。 如果没有,你需要一个像@keys = sort keys %hash
这样的辅助索引 - 它也可以是一个二叉树,但这很简单就应该有一个简单的列表(如果速度不重要,你甚至可以这么做懒惰的搜索自下而上,而不是实现二进制搜索)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.