我有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;
答案 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
部分会传递给$_
一个计数,否则会传递零。