Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Printing largest number in array using loops and if statement

by matze77 (Friar)
on Jan 16, 2010 at 17:56 UTC ( [id://817782]=perlquestion: print w/replies, xml ) Need Help??

matze77 has asked for the wisdom of the Perl Monks concerning the following question:

Hello Fellow Monks!
In an online course about learning perl there was given the task:

Print the largest number in a given array using loops and if statements
.

(Sorting the array which seems the simplest solution for me was not wished ...)
This was my solution:

#!/usr/bin/perl #Commented Padre relict:use 5.006; #use strict; use warnings; @array = (5,2,4,9,45,3,10,7,99,12); $big = 0; foreach (@array) { if ($_ > $big) { $big = $_; } } print "$big\n";
Do you have maybe better solutions or alternate interesting solutions to accomplish this?
Thanks
MH

Replies are listed 'Best First'.
Re: Printing largest number in array using loops and if statement
by hossman (Prior) on Jan 16, 2010 at 18:17 UTC

    what if the input array contains negative numbers?

    start with $big = $array[0] instead.

      start with $big = $array[0] instead
      You spotted the logical error!. Well done.

      But now your loop has one iteration too many as the first time into the loop the test necessarily fails.

      If you do not have to preserve the original array, you could do $big = shift @array; instead.

      We will leave it to the OP to find a way to avoid the unnecessariy extra turn of the loop and still maintain the original array (without using an extra variable to save the shifted value).

      CountZero

      A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      Yes. I was aware of that. My thought was compare it against an undefined variable? Would this be a possible solution. Maybe i could also compare with: "Greatest negative number perl could use"?. I like your solution its good to see what other people think about the same "problem" even if it is a really small one in this case ...

      Thanks
      MH

Re: Printing largest number in array using loops and if statement
by Limbic~Region (Chancellor) on Jan 16, 2010 at 20:50 UTC
    matze77,
    Here are some reasons why sorting the array to find the maximum value is not a good idea:
    • You either change the order of the array, or waste memory making a copy
    • You spend extra cycles sorting when finding the max is more efficient O(N)

    The implementation you have come up with is usually referred to as the high water mark algorithm. Usually, it looks more like this:

    my $max; for (@list) { $max = $_ if ! defined $max || $_ > $max; }

    If you know for that no value will be less than a certain number, you can set it to that (as you did with 0) or you can assign it to the first value in the list (as suggested elsewhere in this thread) and then loop through the rest of the list. Many would recommend not re-inventing the wheel and would point you to List::Util.

    use List::Util 'max'; print max(@list), "\n";
    I wrote How A Function Becomes Higher Order which may be too advanced but keep the link around for when you are ready. Here are some extra credit ideas to make you consider how you might need to modify the water mark algorithm:
    • Consider you want to know the index of the largest element and not the value
    • Consider you want to the largest value and how many elements in the list are that value
    • Consider if instead of numbers you had strings
    • Consider if what you wanted to know was the element with the most characters

    Cheers - L~R

      Hmm. I must admit i do not fully understand that line of code, perhaps if written in more lines it is better to understand:

      $max = $_ if ! defined $max || $_ > $max;
      Could one say if $max is not defined (set to a value maybe this could occure on first iteration?). or $_ is greater than $_max?. Then $max is set to $_?

        Yes, that is what it means. Any time you have stmt if cond, it can be rewritten as
        if (cond) { stmt; }
        So, in this case, that line is equivalent to
        if (! defined $max || $_ > $max) { $max = $_; }
        Personally, I prefer the method of initializing $max to the first (defined) item in the list so as to avoid testing !defined $max on every pass. The performance benefit of avoiding that test is negligible, of course, but it reads more cleanly to me when you're able to just say "remember this as the highest value if it's greater than the previous highest value" without the extra "and a highest value has been previously set" clause.
Re: Printing largest number in array using loops and if statement
by CountZero (Bishop) on Jan 16, 2010 at 19:10 UTC
    Looks OK, but now do it again and uncomment the use strict; pragma.

    Always use strict;, even for small programs until it becomes second nature.

    Is there a reason why you added use 5.006?

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

        I fully agree that including a minimum Perl version is good coding practice, provided of course you know what you are doing and why you are doing it. In this case there is no reason to have a minimum version of Perl 5.6 and as the code was an exercise, one must check every statement and see whether it is correct and necessary.

        Update: Actually, according to Perl::MinimumVersion, the use warnings; pragma pushes the miminum version up to Perl 5.6.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

        No. That is what padre scripts default to if new scripts are made ... Sometimes i forget to remove it ... http://padre.perlide.org

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://817782]
Approved by JSchmitz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (7)
As of 2024-03-29 15:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found