Re: finding highest number
by BrowserUk (Patriarch) on Dec 05, 2002 at 12:58 UTC
|
#! perl -slw
use strict;
my @numbers = (3, 2, 1);
my $highest;
## NOTE Perl arrays start from 0 (zero) not 1 (one).
for (my $i = 0; $i < @numbers; $i++) {
print "Comparing $numbers[$i] with $numbers[$i+1]";
if ($numbers[$i] > $numbers[$i + 1]) {
print "Setting \$highest to $numbers[$i]";
$highest = $numbers[$i];
}
}
print $highest;
__END__
prints C:\test>217736
Comparing 3 with 2
Setting $highest to 3
Comparing 2 with 1
Setting $highest to 2
Use of uninitialized value in concatenation (.) or string at C:\test\2
+17736.pl line 8.
Comparing 1 with
Use of uninitialized value in numeric gt (>) at C:\test\217736.pl line
+ 9.
Setting $highest to 1
1
Does that make it any clearer for you?
Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
Just be grateful that you arrived just as the tornado season finished. Them buggers are real work. | [reply] [d/l] [select] |
Re: (nrd) finding highest number
by newrisedesigns (Curate) on Dec 05, 2002 at 12:53 UTC
|
my @sorted = sort {$b <=> $a} @numbers;
my $highest = $sorted[0];
This sorts your array from highest to lowest and puts it in @sorted.
Update: changed "my $highest = $numbers[0];" to "my $highest = $sorted[0];" Many thanks to UnderMine for pointing this out.
John J Reiser
newrisedesigns.com | [reply] [d/l] |
|
This may be Perlish, but it is also rather inefficient: O(n*log(n)) vs. O(n).
If you want to do it the Perlish way, why not use max that can be found in the wonderful List::Util module?
Just my 2 cents, -gjb-
| [reply] [d/l] |
|
Oddly enough, it's more efficient to use sort rather than an explicit Perl loop for for up to a dozen or two elements, if I recall the benchmarks.
Of course, List::Util has a max function, which would be faster still.
But don't be so quick to optimize... you may be unoptimizing.
-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.
| [reply] |
|
my $highest =(sort {$b <=> $a} @numbers)[0];
This is a bit more compact
Hope it helps
UnderMine | [reply] [d/l] |
|
thanks but i need to keep the order of the array intact for the next stage.
;-)
| [reply] |
|
| [reply] [d/l] [select] |
Re: finding highest number
by LTjake (Prior) on Dec 05, 2002 at 12:56 UTC
|
It's because you're only comparing the current and next numbers in the array. The way I would do it, is keep track of the highest number in another variable. The variable is initialized to the first number in the array.
use strict;
my @array = (1, 5, 4, 10, 20, 2, 1, 3, 7);
my $highest = $array[0];
foreach (@array) {
$highest = $_ if $_ > $highest;
}
print $highest;
Which gives me 20. I'm sure there are prettier ways, but this seems to work.
Update: and of course, the perlish way would be to use sort. duh. ++newrisedesigns. I need a coffee.
-- "I don't intend for this to take on a political tone. I'm just here for the drugs." --Nancy Reagan | [reply] [d/l] [select] |
|
No... that would be known as the slow way. This is an operation which should only have to traverse the array *once* where sort() has higher overhead (perhaps gjb has it right as O(n*log(n)) versus O(n)).
The better answer is to use something akin to what you posted. I'd want to check for undefined values as well. For an answer I just copied right from a toy mapping app I just coded up last night.
sub max { my $m;
for (@_) {
next unless defined;
$m = $_, next unless defined $m;
$m = $_, next if $m < $_;
}
$m }
__SIG__
use B;
printf "You are here %08x\n", unpack "L!", unpack "P4", pack
"L!", B::svref_2object(sub{})->OUTSIDE;
| [reply] [d/l] [select] |
|
thanks LTjake this is cool, but how could you adapt it to calculate
second and third highest numbers also??
| [reply] |
|
    how could you adapt it to calculate second and third highest numbers?
something like:
use strict;
my @array = (1, 5, 4, 10, 20, 2, 1, 3, 7);
my @hi = (0) x 3; # '0' assumes positive #'s
foreach (@array) {
$_ <= $hi[0] and next;
@hi = (sort $a<=>$b, @hi, $_)[-3..-1];
}
print "@hi";
(untested)   (and, as said, of course the sort method would be better, at least for small arrays, and would be even more better for finding the top three values:  (sort ..., @array)[-3..-1] )
  p | [reply] [d/l] [select] |
Re: finding highest number
by thinker (Parson) on Dec 05, 2002 at 13:03 UTC
|
Hi,
There is a flaw in your logic. A corrected version is here.
Notice how the List::Util::max function does what you want.
#!/usr/bin/perl -w
use strict;
use List::Util; #for the max function
my @numbers = qw( 10 4 7 2 5 8 1 3 11);
my $highest=$numbers[0]; # Initialise this for case of all negatives
for (my $i = 1; $i < @numbers; $i++) {
if ($numbers[$i] > $highest) { #compare to the previous hig
+hest
$highest = $numbers[$i];
}
}
print "\$highest is $highest\n";
#now use List::Util::max
print "Max is ", List::Util::max(@numbers),"\n";
hope this helps
thinker
| [reply] [d/l] |
Re: finding highest number
by RMGir (Prior) on Dec 05, 2002 at 12:59 UTC
|
(I smell homework, maybe... Oh well.)
There are a couple of problems with your code.
By looking at $numbers[$i+1], you're going to be reading past the end of the array... Not really a serious problem in perl, but something to keep in mind. You're also skipping element 0 in the array.
You'll also mark as highest any value that's followed by a lower number. So if @numbers is (1,0,100,0,2,0), you'll get 2 instead of 100.
You should be comparing $numbers[$i] with the highest value you've seen so far.
# we assume numbers was set up somewhere above...
my $highest;
# we'll get undef if @numbers is empty
$highest=$numbers[0] if @numbers;
for(my $i=1; $i<@numbers; $i++) {
if($numbers[$i]>$highest) {
$highest=$numbers[$i];
}
}
print $highest;
--
Mike | [reply] [d/l] [select] |
Re: finding highest number
by FamousLongAgo (Friar) on Dec 05, 2002 at 12:59 UTC
|
For one thing, you are ignoring the first element of the array ( Perl arrays are zero-based ), and comparing phantom elements at the end of the array. For example, if you have this array:
@stuff = ( 90, 5, 4 );
Your code will start with the second element, and compare the last element to a nonexistent ( and therefore undefined ) value ( $stuff[3] ).
For another thing, you are resetting the value of $highest every time a following element has a lower value. With the code as it now exists, $highest will always be the last element in the array. I urge you to work this out by hand with the short example.
Here is something that does what you want:
my $highest = 0;
foreach my $element ( @numbers ) {
$highest = $element if $element > $highest;
}
print $highest;
| [reply] [d/l] [select] |
Re: finding highest number
by gjb (Vicar) on Dec 05, 2002 at 12:57 UTC
|
Simply compare $numbers[$i] with $highest rather than $numbers[$i+1], initializing $highest = $numbers[0] (outside of the for).
Hope this helps, -gjb-
| [reply] [d/l] [select] |
Re: finding highest number
by Chief of Chaos (Friar) on Dec 05, 2002 at 13:02 UTC
|
If you don't want to use sort, try this :
if (scalar(@numbers) > 0) {
# compare only when array has entries
my $highest = $numbers[0]; # set startvalue
foreach my $compNum (@numbers){
# compare all numbers in array
$highest = $compNum if ($compNum > $highest);
}
} else {
# nothing to compare
}
ps: code is not tested | [reply] [d/l] [select] |