Re: How to get 2nd highest value from an array?
by GrandFather (Saint) on Dec 13, 2005 at 17:37 UTC
|
use warnings;
use strict;
my @list = (4, 7, 1, 3, 2, 9);
my $second = (sort @list)[-2];
print $second;
Prints:
7
DWIM is Perl's answer to Gödel
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] |
Re: How to get 2nd highest value from an array?
by davidrw (Prior) on Dec 13, 2005 at 17:37 UTC
|
doesn't take into account short (or string/custom sorts) lists, but as a starting point:
my @arr = qw/ 1 9 8 7 6 2 3 4 5/;
print ( (sort @arr)[-2] );
| [reply] [d/l] |
Re: How to get 2nd highest value from an array?
by jeffa (Bishop) on Dec 13, 2005 at 17:57 UTC
|
Update: Oops, i actually meant to say: Is there anyway to do this same thing on the values of a hash?
Do you mean just the values themselves or the keys based on the values? Here is some code for both cases:
my %hash = (
4 => 20, # second highest key
2 => 40, # second highest value
3 => 30,
1 => 50,
5 => 10,
);
# second highest value
print ((sort values %hash)[-2]);
# key based on the second highest value
print ((sort { $hash{$b} <=> $hash{$a} } keys %hash)[1]);
For the second example, since we already have to specify a sort block, i choose to sort descending and use the subscript 1 and not -2. TIMTOWTDI. :)
| [reply] [d/l] |
Re: How to get 2nd highest value from an array?
by choedebeck (Beadle) on Dec 13, 2005 at 17:59 UTC
|
This was actually an interview question I had for my first job, only I had to do it in C. Here is a solution without a sort.
sub getSecondLargest
{
my (@list) = @_;
my ($largest, $secondlargest);
for(my $i = 0;$i<=$#list;$i++)
{
if($i == 0)
{
if($list[0] >= $list[1])
{
($largest, $secondlargest) = ($list[0], $list[1]);
}
else
{
($largest, $secondlargest) = ($list[1], $list[0]);
}
}
if($i >=3)
{
if($list[$i] >= $largest)
{
$secondlargest = $largest;
$largest = $list[$i];
}
elsif($list[$i] >= $secondlargest)
{
$secondlargest = $list[$i];
}
}
}
return $secondlargest;
}
| [reply] [d/l] |
|
|
Even if it was in C, I'd still call qsort to get the answer, rather than write a lot of code {grin}.
| [reply] |
Re: How to get 2nd highest value from an array?
by gjb (Vicar) on Dec 13, 2005 at 18:12 UTC
|
If the list (or hash) is large, first doing a sort is a Really Bad IdeaTM given that this is an O(n log n) operation. As choedebeck's code above illustates it can be done in time linear in the size of the list/hash, i.e., O(n). This is a significant difference for large values of n.
Hope this helps, -gjb-
| [reply] [d/l] |
Re: How to get 2nd highest value from an array?
by GrandFather (Saint) on Dec 13, 2005 at 20:39 UTC
|
use warnings;
use strict;
my %hash = (4 => '1', 5 => '5', 7 => '2', 1 => '7', 10 => '9', 3 => '0
+', 2 => '3', 9 => '8');
print GetSecondLargest(values %hash);
sub GetSecondLargest
{
my @largest = (shift);
while (@_)
{
my $new = shift;
if ($new >= $largest [-1])
{
unshift @largest, $new;
next;
}
$largest[1] = $new if ! $#largest or $new > $largest[1];
}
return $#largest ? $largest[1] : undef;
}
Prints:
8
DWIM is Perl's answer to Gödel
| [reply] [d/l] [select] |
Re: How to get 2nd highest value from an array?
by l.frankline (Hermit) on Dec 13, 2005 at 22:59 UTC
|
@arr = (1..10);
print sort($arr[$#arr]-1);
Regards Franklin
Don't put off till tomorrow, what you can do today.
| [reply] [d/l] |
|
|
Well the code above prints value-1 of the last element not the value of the next to last element. In an array of sequential numbers the result may be the same ie element 9 contains value 9.
So the print statement becomes
print sort($arr[$#arr-1]);
?
| [reply] [d/l] |
Re: How to get 2nd highest value from an array?
by Nilotpal_1984 (Initiate) on Jun 24, 2017 at 01:09 UTC
|
# code to get second highest number without sort.
#!/usr/bin/perl
use strict ;
my @arr = qw(4 4 0 -1 -2 2 0 1) ;
my $f = $arr[0] ;
my $s = $arr[0] ;
for (my $i=1 ; $i<@arr; $i++) {
if ($arr[$i] > $f) {
$s = $f ;
$f = $arr[$i] ;
} elsif (($arr[$i] > $s || (($f == $s))) && $arr[$i]!=$f) {
$s = $arr[$i] ;
}
}
if ($f == $s) {
print "\n there is no second greatest number" ;
} else {
print "\n second highest number : $s" ;
}
| [reply] [d/l] |