我有以下向量:
19.01
20.2572347267
16.4893617021
19.0981432361
36.3636363636
20.41
它实际上要长得多,但这并不重要。我需要一个算法来将这些值放入散列中。哈希键必须是从最小值+1(在本例中为17.48…)开始并增加1的浮点值。散列的值必须是落入相应bin的元素数量,即最终结果应该是:
$hash{17.49}=1
$hash{18.49}=0
$hash{19.49}=2
$hash{20.49}=2
$hash{21.49}=0
$hash{22.49}=0
.
.
.
$hash{35.49}=0
$hash{37.49}=1
请帮帮伙计们。
这似乎有效:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
use List::Util qw{ min };
my @vector = qw( 19.01
20.2572347267
16.4893617021
19.0981432361
36.3636363636
20.41
);
my %hash;
my $min = min(@vector);
for my $n (@vector) {
my $diff = $n - $min;
++$hash{ 1 + $min + int $diff };
}
print Dumper %hash;
如果你也需要零,只需在循环之前添加以下内容:
my $max = max(@vector);
my $i = $min;
while ($i <= $max) {
$hash{$i++} = 0;
}
(在use
子句中也包含max
。)
想出了一个不错的解决方案,希望其他人也会觉得它有帮助。
use POSIX;
sub frac { $_[0]-floor($_[0]) } #saw this little function posted somewhere, quddos to the guy who came up with it
for (my $x = ${min_value} + 1; $x <= ${max_value} + 1; $x += 1) # if you don't need the zeroes, remove this loop
{
$bins{$x} = 0;
}
foreach my $n (@array)
{
$bins{floor($n+1)+frac($min_value)}++;
}
应该使用floor()或ceil()(并使用POSIX;)来代替int(),因为int()可以产生不同的结果-278可能在内部存储为277.99999999997899999(例如),所以int(278)等于277,这可能会打乱计算。在某处阅读,但找不到链接。。。