0

I only get the smaller element as output although there are 2 elements with same highest occurrence in array

I have tried to remove sort function from the codes but it still returns me the smaller element

my(@a) = (undef,11,12,13,14,15,13,13,14,14); 
my(%count); 
foreach my $value (@a) { 
  $count{$value}++; 
}
$max_value = (sort {$count{$b} <=> $count{$a}} @a)[0]; 
print "Max value = $max_value, occur $count{$max_value} times\n";

Expected result: Max value =13 14, occur 3 times

Dave Cross
  • 68,119
  • 3
  • 51
  • 97

2 Answers2

2

max_by from List::UtilsBy will return all values that share the maximum in list context.

use strict;
use warnings;
use List::UtilsBy 'max_by';

my @a = (undef,11,12,13,14,15,13,13,14,14);
my %count;
$count{$_}++ for @a;
my @max_values = max_by { $count{$_} } keys %count;
Grinnz
  • 9,093
  • 11
  • 18
1

Your code simply takes the first maximal value it finds in the sorted data. You need to continue reading array elements until you reach one that is no longer maximal.

However, as you probably have to test all the hash values there's no great advantage to sorting it. You can just traverse it and keep track of the maximal value(s) you find.

my @a = (undef,11,12,13,14,15,13,13,14,14);

my %count;
$count{$_}++ for @a;

my ($max_count, @max_values);
while ( my ($k,$v) = each %count) {
    if ($v > $max_count) {
        @max_values = ($k);
        $max_count = $v;
    }
    elsif ($v == $max_count) {
        push @max_values, $k;
    }
}

my $max_values = join " ", sort @max_values;

print "Max value = $max_values, occur $max_count times\n";

Note that undef is not a valid hash key - it gets converted to "".

jhnc
  • 11,310
  • 1
  • 9
  • 26
  • Hi Jhnc, Yeah, make sense, it needs to continue searching after getting the first element with highest occurrence. Thanks for the sharing and it's working :) – user6201481 Jul 04 '19 at 04:47
  • @ikegami thanks. I naively assumed traversing the hash twice would be slower but it seems it depends on the hash size. With the sample data, yours seems to be about 20% faster but with large hash (~1M elements), mine become about 50% faster. Your version is certainly cleaner though! – jhnc Jul 04 '19 at 21:30
  • They are both O(N), which means they scale identically. But, mine has fewer Perl operations, so less overhead. – ikegami Jul 04 '19 at 21:33
  • oh, missed the last part ("mine become about 50% faster"). So ignore the second sentence. They both scale identically (O(N)), which means no big surprises when you scale up. – ikegami Jul 04 '19 at 22:18