Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Binary search

by akvats01 (Initiate)
on Mar 29, 2013 at 15:01 UTC ( #1026159=perlquestion: print w/replies, xml ) Need Help??
akvats01 has asked for the wisdom of the Perl Monks concerning the following question:


I am beginner in perl.

I have implemented binary search for leaning purpose. The code shows abrupt results. For few items in the list, it returns the exact position, but it is not able to find out the position of other elements especially towards the end of array.

Like the Key is 2,65 etc the result is 1 but if the key is 34,100,or 42 etc the result is : not found

I wonder, if this code is not working it should not work for any thing. Please tell me where am I wrong.

Code :

#!/usr/bin/perl @num_list=(34,2,65,345,987,23,12,45,62,100); $low=0; $found_key=0; $index; $high=$#num_list; print "enter the key: \t"; chomp($key=<STDIN>); while($high>=$low && !$found_key) { $mid=($low+$high)/2; if ($key == @num_list[$mid]) { $found_key=1; $index = int($mid); } if ($key > @num_list[$mid]) { $low = $mid+1; } if ($key < @num_list[$mid]) { $high = $mid-1; } } if ($found_key) { print " The key is $index\n"; } else {print "Not found";}

Replies are listed 'Best First'.
Re: Binary search
by moritz (Cardinal) on Mar 29, 2013 at 15:05 UTC

    A binary search only works in a sorted list, but your @num_list isn't sorted.

Re: Binary search
by davido (Archbishop) on Mar 29, 2013 at 16:33 UTC

    There's a good discussion on Binary Searches with Perl in Mastering Algorithms with Perl (O'Reilly). I know this is probably homework, but if you need to see several different ways to implement a Binary Search in Perl you can view the source for List::BinarySearch. One of the methods used is adapted from the book mentioned above, and the other methods were based on a composite from several sources including Wikipedia and a couple of other algorithms books I happened to have.

    But moritz is right: If your list isn't sorted to begin with, a Binary Search won't produce useful results. You'll either need to sort the list, or do a linear search.


Re: Binary search
by LanX (Bishop) on Mar 29, 2013 at 15:09 UTC
Re: Binary search
by akvats01 (Initiate) on Mar 29, 2013 at 16:50 UTC

    Thanks to everybody. my apologies that code was not readable smoothly. This was my first post, I will take care next post onwards. to sort the list , I have used

    @num_list1= (34,2,65,345,987,23,12,45,62,100); @num_list= sort {a <=> b} @num_list1;
    Still I am seeing the same results. I am due to read the algo implementation as mentioned above. meanwhile I will be thankful, if some light can be thrown on , why the code is working partially. What should I keep in mind : Not to entre in such a situation again where code is working partially. Thanks!!


      @num_list= sort {$a <=> $b} @num_list1;

      would work better.... ;^)


      When your only tool is a hammer, all problems look like your thumb.

      Thanks to everyone. I have sorted the array as follows

      @num_list1=(34,2,65,345,987,23,12,45,62,100); @num_list= sort {a <=> b} @num_list1;
      Still the same results are shown. I am due to go through the algorithm implementation mentioned above. Meanwhile, I will be thankful if some light may be thrown on why the code is working partially? what precautions should I take to avoid this situation when code is working partially. Thanks.

      My apologies for code not being readable. The original code, after implementing sort is :

      #!/usr/bin/perl @num_list1=(34,2,65,345,987,23,12,45,62,100); @num_list= sort {a <=> b} @num_list1; $low=0; $found_key=0; $index; $high=$#num_list; print "enter the key: \t"; chomp($key=<STDIN>); while($high>=$low && !$found_key) { $mid=($low+$high)/2; if ($key == @num_list[$mid]) { $found_key=1; $index = int($mid); } if ($key > @num_list[$mid]) { $low = $mid+1; } if ($key < @num_list[$mid]) { $high = $mid-1; } } if ($found_key) { print " The key is $index\n"; } else {print "key is not found";}
        Hi akvats01,

        Did you try printing out the sorted list to make sure it got sorted correctly?

        I did, and got:

        print "Sorted => @num_list\n"; # Output: Sorted => 34 2 65 345 987 23 12 45 62 100

        So the sort isn't working. Now that I know that's a problem, I look at your sort line more carefully:

        @num_list= sort {a <=> b} @num_list1;
        And it's obvious what's wrong; you should use "$a" and "$b". You would have found that if you used the "strict" and "warnings" pragmas. Try running this partial program and you'll see:
        #!/usr/bin/perl use strict; use warnings; my @num_list1=(34,2,65,345,987,23,12,45,62,100); my @num_list= sort {a <=> b} @num_list1; print "Sorted: @num_list\n"; # Output: # # Bareword "a" not allowed while "strict subs" in use at li +ne 7. # Bareword "b" not allowed while "strict subs" in use at li +ne 7. # Execution of aborted due to compilation errors.
        The other (potential) problem I can see is that you are not doing integer math, so when you take the average of $low and $high with:
        $mid = ($low+$high)/2;
        you're sometimes getting a fractional result. You may need to use int to fix that.

        Try those fixes to start with and see if you can get farther. One other recommendation would be to put print statements at various locations in your code to make sure you're getting the expected results each time through the loop.

        say  substr+lc crypt(qw $i3 SI$),4,5

        This line will produce a non-integer value with an odd number of elements, which can't be an index of an array.

        If you use the following at the top of your scripts and make the necessary corrections for it to compile, it will make your life easier and your code better.
        use strict; use warnings;

        Update: I see now that an array can be indexed with a non-integer value, effectively truncating the fractional part. I'm surprised that gives no warning.

        use strict; use warnings; use feature 'say'; my @list = 0..9; say $list[2.5]; say $list[2.01]; say $list[2.99]; # all these print '2'
        golux is correct of course about the sort, which is something that enabling 'strict' and 'warnings' would pick up.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1026159]
Approved by davido
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (8)
As of 2018-07-16 07:08 GMT
Find Nodes?
    Voting Booth?
    It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?

    Results (333 votes). Check out past polls.