0

我有一个哈希值,是否需要将所有“主键”相互比较(这些是数字)。这是我的代码:

foreach my $masterkey1 (keys %HOH){
foreach my $masterkey2 (keys %HOH){
        if ($masterkey1 > $masterkey2){
            ... do some stuff...
        }
    }
}

然而,为了减少内存使用,可以将 if 语句与第二个 foreach 循环结合使用。

也许像

foreach my $masterkey1 (keys %HOH){
    foreach my $masterkey2 (keys %HOH < $masterkey1){
        ... do some stuff...
    }
}
  • 谢谢 :)
4

3 回答 3

2
foreach my $masterkey1 (keys %HOH){
    foreach my $masterkey2 (grep { $_ < $masterkey1 } keys %HOH){
        ... do some stuff...
    }
}

我不确定这会更有效。内部循环必须通过键执行两次:一次查找所有小于 的键$masterkey1,然后实际“做一些事情”。

最好将密钥列表保存在一个单独的变量中:

@keys = keys %HOH;
foreach my $masterkey1 (@keys) {
    foreach my $masterkey2 (@keys) {
        if ($masterkey1 > $masterkey2) {
           # do some stuff
        }
    }
}
于 2013-04-30T08:20:53.670 回答
1

复制和排序键:

my @keys = sort { $a <=> $b } keys %HOH;

现在列表已排序,您可以从列表末尾获取每个键并将其与之前的所有内容进行比较:

while (my $masterkey1 = pop @keys) {
    foreach my $masterkey2 (@keys) {
        # do some stuff with $masterkey1 and $masterkey2
    }
}
于 2013-04-30T09:41:12.207 回答
1

您可能不希望有两个嵌套循环扫描您的键列表。运行所需的时间将随着顶级散列中键的数量呈指数增长,这可能会导致重大问题,除非散列(并且将始终保持)相对较小。

您没有说您真正想要完成什么,但是,由于您正在比较更大的值,您可能希望从sort. 我能给你的最好的功能与发布的代码相同的是:

my @masterkeys = sort { $a <=> $b } keys %HOH;
for my $outer (1 .. $#masterkeys) {
  for my $inner (0 .. $outer - 1) {
    # We already know $masterkeys[$outer] > $masterkeys[$inner],
    # so no need to test that
    ... do some stuff ...
  }
}

这至少会比您发布的代码更有效率,但是,如果您告诉我们您实际上想要完成的工作,我怀疑仍有很多改进的可能。

编辑: 根据 OP 对此答案的评论,“我需要比较所有主密钥并计算它们共有多少个密钥。

以下是如何在两个哈希中找到公共键:

my %count;
$count{$_}++ for keys %hash1;
$count{$_}++ for keys %hash2;
my @keys_in_common = grep { $count{$_} == 2 } keys %count;

此过程所需的时间将随着两个哈希中的键总数线性增加,因此对于非常大的数据集仍然有效。

于 2013-04-30T10:03:08.807 回答