Re: max of N numbers?
by revdiablo (Prior) on May 27, 2006 at 18:05 UTC
|
| [reply] |
Re: max of N numbers?
by Fletch (Bishop) on May 27, 2006 at 17:31 UTC
|
Ah yes, the perennial "I want to do X without using way every sane programmer does X" question.
my @list = qw( 4 30 2 54 1 2 );
print "Which of these numbers is the largest:\n", join( "\n", @list ),
+ "\n";
chomp( my $max = <STDIN> );
See also the mechanical turk. For the saner answer, see max in List::Util.
| [reply] [d/l] [select] |
A reply falls below the community's threshold of quality. You may see it by logging in. |
Re: max of N numbers?
by GrandFather (Saint) on May 27, 2006 at 19:29 UTC
|
use strict;
use warnings;
use List::Util qw(min);
my @nums = (3,9,12);
my $foo = min (@nums);
print $foo;
Prints:
3
DWIM is Perl's answer to Gödel
| [reply] [d/l] [select] |
Re: max of N numbers?
by TedPride (Priest) on May 27, 2006 at 20:04 UTC
|
There is no way to find the max of N numbers without using comparison operators. However, you can just add a short function to your code for finding max:
use strict;
use warnings;
my @arr = (2,7,12,5,17,9);
print max(@arr);
sub max {
my $max = $_[0];
do { $max = $_[$_] if $max < $_[$_]; } for 1..$#_;
$max;
}
This takes linear time. Or you can use a sort, which takes O(n lg n) time:
my $max = (sort { $b <=> $a } @arr)[0];
| [reply] [d/l] [select] |
Re: max of N numbers?
by swampyankee (Parson) on May 27, 2006 at 19:14 UTC
|
#!perl
use strict;
use warnings;
my $vector = (1,23, 3, 2.0**37, -1.0 * 10 ** (-41), 10.0**19);
my $max;
$max = $vector[0];
$max = $_ if $max > $_ foreach (@vector[1..$#vector]);
print "$max\n";
You'll be comparing them implicitly with a call to a routine like
$max = max (@vector);
which uses comparisons internally.
So the literal answer to your question is "no" you can't find the number with the largest or smallest value of a group of values without comparison operators. You can, however, hide the comparison operators in a function.
emc
"Being forced to write comments actually improves code, because it is easier to fix a crock than to explain it. " —G. Steele
| [reply] [d/l] [select] |
Re: max of N numbers?
by spiritway (Vicar) on May 27, 2006 at 18:14 UTC
|
Depends on what you mean by "quick"; and it also depends on how you define "comparison operators". You *could* use the spaceship operator ( '<=>' )and sort the list of numbers. That involves, of course, a comparison. You could convert all the values into strings, with leading zeroes sufficient to ensure all the numbers have the same number of digits before the decimal point; then sort as before; this sort uses an implicit comparison. I'm not sure how quick these sorts would be.
The question that seems more important is why you would want to perform a comparison task, without using operators that are wholly appropriate for that purpose. Unless you meant, not having to use the '=', '>' and '<' operators separately...
| [reply] [d/l] |
Re: max of N numbers?
by pingo (Hermit) on May 27, 2006 at 18:28 UTC
|
| [reply] |
Re: max of N numbers?
by Anonymous Monk on May 27, 2006 at 20:16 UTC
|
Although I don't agree with the question, an interesting solution does exist, I guess... Don't have time to explain it, but it's not that hard to figure out.
#!/usr/bin/perl
use strict;
use warnings;
my @n = (2,3,4,7,8,9,10,8,20,9,7);
my $m;
foreach my $x (@n) {
for (0..$#n) {
my $y = $n[$_];
my $diff = abs($x - $y);
$m = $x if $_ == $#n;
next if $diff == 0;
last if $diff + $x == $y; # Then y > x.
}
}
print $m;
| [reply] [d/l] |
|
|
| [reply] [d/l] |
|
|
Sorry, I got lazy and didn't complete the code. You can get rid of the ==s by simply subtracting the rhs from the left
if $x == $y;
if $x - $y;
| [reply] [d/l] |
Re: max of N numbers?
by Anonymous Monk on May 27, 2006 at 20:25 UTC
|
Thanx to all of you...
I used
use List::Util qw(min);
and it worked just fine... That's what I meant by "quick way".. not having to use <,>,=, lots of arrays and comparisons... I am new to modules and I didn't know List::Util. | [reply] [d/l] |
|
|
It's interesting that you're using min() to find the "max of N numbers". Pedantics aside, it's worthy of mention that the "quick way" still has to internally iterate over every element in the list you hand it, keeping track of the max. There's no way to determine the max in a list in less than O(n) time unless the list is already sorted in some fashion. And sorting a list just to grab the max one time is less efficient still. So assuming a list of arbitrary order, ascertaining the max is going to cost you O(n). The max() routine built into List::Util, at least, does this in C, so it's pretty overhead efficient, but the basic algorithm is still essentially a linear scheme with lots of internal comparisons.
The fact is that the best approach really is going to be determined by what it is you're trying to accomplish. A quick check for the max in a short list, infrequently, is best handled by List::Util max(). But more frequent searches of longer lists might benefit from a scheme to maintain order in the list in the first place. If I remember correctly, with a heap, initial heap creation consumes O(n log n) time, whereas simple linear list creation consumes O(n) time. Additional insertion consumes O(log n) time, again worse than the O(1) time required to insert an additional number in a linear list. But the benefit comes when you need to find the top element in the heap (which can be max or min depending on how you construct it to begin with). Grabbing the top element off a heap consumes O(1) time, as does simply peeking at the top element. So in some cases a heap might be preferable to a linear list, particularly if you don't care about order except to find the biggest or smallest element easily at all times, frequently, for large dynamically changing lists. On the other hand, for simple cases, ignore all this heap talk and just use List::Util max() ...or min().
| [reply] [d/l] [select] |