Perl - 标识散列中具有最高值的所有元素

时间:2015-02-11 20:40:17

标签: arrays perl hash

我编写了一些Perl代码,用于搜索哈希中的最高键值对,其中键是文本,值是数字:

my $o_val = 0;    # FOR TRACKING HIGHEST VALUE ENCOUNTERED IN THE LOOP
my $o_key;        # FOR TRACKING CORRESPONDING KEY TO THE HIGHEST VALUE
while ( my ($key, $val) = each(%NG) ) {
        if ( $val > $o_val ) {
                $o_val = $val;
                $o_key = $key;
        }
}
print "$okey\n";

问题在于它没有考虑到最高价值并列的可能性。 如果我的测量变量可能随循环的每次迭代发生变化,我如何捕获所有与最高值相关的键值对?

我有一个想法是,在$ o_val被建立为最高值之后,我可以编写另一个while循环来运行相同的散列,然后将每个与$ o_val配对的键推送到另一个数组中,例如:

my @highest;     # ARRAY OF HIGHEST-VALUE KEYS
while ( my ($key, $val) = each(%NG) ) {
    if ( $val == $o_val ) { push(@highest, $key); }
}

但这看起来效率低下。我希望有一些Perl命令,我不知道这会让我在没有循环的情况下识别散列中的最高值,所以我可以在我的问题中使用第二段代码。

2 个答案:

答案 0 :(得分:5)

您可以使用数组来保持键值最高,

if ( $val > $o_val ) {
  $o_val  = $val;
  @o_keys = $key;
}
elsif ($val == $o_val) {
  push(@o_keys, $key);
}

答案 1 :(得分:2)

#!/usr/bin/env perl

use strict;
use warnings;

my %h = map { $_ => int(rand 10)} 'a' .. 'z';

# see what we've got
my @k = sort { $h{$b} <=> $h{$a} } keys %h;
print "$_ => $h{$_}\n" for @k;

# initialize $max with a value from %h
my ($max) = values %h;
# keys with highest values
my @argmax;

while (my ($k, $v) = each %h) {
    next if $v < $max;
    if ($v > $max) {
        $max = $v;
        @argmax = ($k);
    }
    else {
        push @argmax, $k
    }
}

print "@argmax\n";
print "@h{ @argmax }\n";

当然,如果你不太关心记忆,或者如果你正在打高尔夫球或日本人,你可以写下这样的话:

my %v;
push @{ $v{$h{$_}} }, $_ for keys %h;
my ($max) = sort { $b <=> $a } keys %v;
print "@{ $v{$max} } => $max\n"