我有数组的哈希,
我想将哈希元素与常用数字合并。
例如。 输入哈希
%HoA_output = (
A1 => [ "1", "2", "3", "4", "9", "10", "11", "12", "13", "14" ],
A2 => [ "5", "6", "7", "8" ],
);
输出哈希
Options -Indexes
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://(www\.)?REMOVEDLINK [NC]
RewriteCond %{HTTP_REFERER} !^http://(www\.)?REMOVEDLINK.*$ [NC]
RewriteRule \.(gif|jpg|png|js|css)$ - [F]
ErrorDocument 403 http://REMOVEDLINK/404.html
ErrorDocument 404 http://REMOVEDLINK/404.html
我需要一个能够快速评估具有近50k密钥的哈希的解决方案,每个阵列中有8个数字。
问候
答案 0 :(得分:3)
好的,从根本上说 - 这不是一件容易的事,因为你需要相互检查每个元素,看看它们是否存在。我能想到的最好的方法是通过合并列表来节省一些精力,并使用索引来跟踪欺骗。
我会这样做:
use strict;
use warnings;
use Data::Dumper;
my %HoA = (
A1 => [ "1", "2", "3", "4" ],
A2 => [ "5", "6", "7", "8" ],
A3 => [ "1", "9", "10", "11" ],
A4 => [ "12", "13", "14", "10" ],
);
print Dumper \%HoA;
my %found;
sub merge_and_delete {
my ( $first_key, $second_key ) = @_;
print "Merging $first_key with $second_key\n";
#use hash to remove dupes.
my %elements;
foreach my $element ( @{ $HoA{$first_key} }, @{ $HoA{$second_key} } )
{
$elements{$element}++;
#update index - don't want to point it to an array we're deleting
$found{$element} = $first_key;
}
#sorting for neatness - you might want to do a numeric sort instead,
#as by default %HoA contains text elements.
$HoA{$first_key} = [ sort keys %elements ];
delete $HoA{$second_key};
}
foreach my $key ( sort keys %HoA ) {
print "$key\n";
foreach my $element ( sort @{ $HoA{$key} } ) {
if ( $found{$element} ) {
#this element is present in another list, we merge.
print "$element found in $found{$element}\n";
merge_and_delete( $found{$element}, $key );
last;
}
else {
#add this unique match to our index
print "$element -> $key\n";
$found{$element} = $key;
}
}
}
print Dumper \%HoA;
迭代%HoA
上的每个元素,并创建索引表%found
。此索引表用于检测是否已经看到某个元素,然后触发merge
- 然后重建索引。您可能需要注意大型数据集上的内存消耗,因为您的索引可能会增长到几乎与原始数据集一样大(如果存在足够的唯一元素)。
但是因为我们停止了第一场比赛的处理,我们不再需要检查每个键,因为我们丢弃了合并后的阵列并更新了索引,所以我们不会; t需要进行全面比较。
答案 1 :(得分:3)
这实际上是一个图形问题,您想要确定未连接组件的集合
此解决方案使用Graph::Undirected::Components
模块,其唯一目的就是完成此操作。希望它对你的扩展数据集来说足够快,但你确定它比我更容易
程序创建一个图形,并将数据中每个键的边(连接)添加到其值的每个元素。然后,调用connected_components
将返回彼此连接的所有不同节点集(键和值)
根据节点值是否显示为原始哈希数据中的键,最终for
循环使用List::MoreUtils
中的part
再次过滤来自值的键。 (如果任何键值也可以出现在值中,则必须调整此值。)然后,第一个键与排序值项一起用于在%result
哈希中创建新元素
use strict;
use warnings;
use Graph::Undirected::Components;
use List::Util 'minstr';
use List::MoreUtils 'part';
my %data = (
A1 => [ 1, 2, 3, 4 ],
A2 => [ 5, 6, 7, 8 ],
A3 => [ 1, 9, 10, 11 ],
A4 => [ 12, 13, 14, 10 ],
);
my $graph = Graph::Undirected::Components->new;
while ( my ($k, $v) = each %data ) {
$graph->add_edge($k, $_) for @$v;
}
my %result;
for my $component ( $graph->connected_components ) {
my @keys_vals = part { $data{$_} ? 0 : 1 } @$component;
my $key = minstr @{ $keys_vals[0] };
my @values = sort { $a <=> $b } @{ $keys_vals[1] };
$result{$key} = \@values;
}
use Data::Dump;
dd \%result;
<强>输出强>
{ A1 => [1 .. 4, 9 .. 14], A2 => [5 .. 8] }