Perl中的矢量装箱算法



我有以下向量:

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,这可能会打乱计算。在某处阅读,但找不到链接。。。

最新更新