perl更好的方法来计算每个数组元素的出现次数

时间:2018-04-09 19:48:17

标签: perl machine-learning svm

我有2个数组,一个是根数组,其中包含大量元素。另一个是测试数组,所有元素都是根数组的子集。我想构造一个大小等于根数组的新数组,并且它在特定位置的元素值表示测试数组中该元素的计数。

当2个数组大小很小时,下面的代码很有效。但我遇到的实际问题是,根阵列有大约15000个元素,并且大约有14000个测试阵列 我想知道有更好的算法。你们有什么建议吗?

my @root=qw(1 2 3 4 5 6 7 8 10);
my @aa=qw(1 1 2 3);
my @count;

foreach my $eleroot(@root){
my $mathnum=0;
my ($i) = grep { $root[$_] ~~ $eleroot } 0 .. $#root;
foreach my $eleaa(@aa){
 if ($eleroot==$eleaa){
  $mathnum++;
   }
 }
 $count[$i]=$mathnum;

}
print @count;

my @root=qw(1 2 3 4 5 6 7 8 10); my @aa=qw(1 1 2 3); my @count; foreach my $eleroot(@root){ my $mathnum=0; my ($i) = grep { $root[$_] ~~ $eleroot } 0 .. $#root; foreach my $eleaa(@aa){ if ($eleroot==$eleaa){ $mathnum++; } } $count[$i]=$mathnum; } print @count;

1 个答案:

答案 0 :(得分:1)

更好的算法是使用哈希来保持计数。对于您的示例数组,它看起来像这样。 (而且运行速度会比你的解决方案快得多)。

#!/usr/bin/perl
use strict;
use warnings;

my @root=qw(1 2 3 4 5 6 7 8 10);
my @aa=qw(1 1 2 3);

print join("\t", @root), "\n";

my %seen;
for my $data (@aa) {
    $seen{$data}++; 
}

print join("\t", map {$_ // '0'} @seen{@root}), "\n";   

输出是:

1       2       3       4       5       6       7       8       10
2       1       1       0       0       0       0       0       0

@seen{@root}是由@root数组键入的哈希切片。如果没有找到任何@root元素的项目,则地图会提供零。

如果map {$_ // '0'}有一个计数,则join部分会传递给$_一个计数,否则会传递零。