note 93352 added to function.array-search

From: Date: Fri, 04 Sep 2009 22:57:04 +0000
Subject: note 93352 added to function.array-search
Groups: php.notes 
Request: Send a blank email to php-notes+get-160228@lists.php.net to get a copy of this message
Sometimes you need to find a given value in a sorted array or - if not found - detect the place where it should be. After that you can for example split the array into two halves, the greater and the smaller one. greenmr, dennis.decoene and php at celerondude had all posted very good binary search functions but these functions all return false if the needle was not found in the haystack. I've tweaked greenmr's code a little: <?php function Array_BinarySearch( $needle, $haystack, $comparator , &$probe ) { $high = Count( $haystack ) -1; $low = 0; while ( $high >= $low ) { $probe = Floor( ( $high + $low ) / 2 ); $comparison = $comparator( $haystack[$probe], $needle ); if ( $comparison < 0 ) { $low = $probe +1; } elseif ( $comparison > 0 ) { $high = $probe -1; } else { return true; } } //The loop ended without a match //Compensate for needle greater than highest haystack element if($comparator($haystack[count($haystack)-1], $needle) < 0) { $probe = count($haystack); } return false; } ?> Now, the function returns true if it finds something and false otherwise. If a needle was found, then $probe will contain it's position. Otherwise, $probe will contain position of where the needle would be if it were there :). This is possible because we pass $probe by reference. Example: <?php //ultra-simple comparator :) function CompareNumbers($obj, $needle) { return $obj - $needle; } //use examples $testArr = array(10, 20, 30, 40, 50); $res = Array_BinarySearch(30, $testArr, 'CompareNumbers', $probe); echo (int)$res.' '.$probe.'<br />'; //output is: 1 2 - found at position 2 $res = Array_BinarySearch(45, $testArr, 'CompareNumbers', $probe); echo (int)$res.' '.$probe.'<br />'; //output is: 0 4 - not found, but it would be at position 4 (between 40 and 45) $res = Array_BinarySearch(-3, $testArr, 'CompareNumbers', $probe); echo (int)$res.' '.$probe.'<br />'; //output is: 0 0 - not found, but it would be at position 0 (before 10) $res = Array_BinarySearch(300, $testArr, 'CompareNumbers', $probe); echo (int)$res.' '.$probe.'<br />'; //output is: 0 5 - not found, but it would be at position 5 (after 50; note, that count($haystack) == 5) ?> See original greenmr's note for additional details about usage of this binary search: http://php.net/manual/en/function.array-search.php#89413 ---- Server IP: 82.177.164.100 Probable Submitter: 81.190.111.151 ---- Manual Page -- http://www.php.net/manual/en/function.array-search.php Edit -- https://master.php.net/note/edit/93352 Del: integrated -- https://master.php.net/note/delete/93352/integrated Del: useless -- https://master.php.net/note/delete/93352/useless Del: bad code -- https://master.php.net/note/delete/93352/bad+code Del: spam -- https://master.php.net/note/delete/93352/spam Del: non-english -- https://master.php.net/note/delete/93352/non-english Del: in docs -- https://master.php.net/note/delete/93352/in+docs Del: other reasons-- https://master.php.net/note/delete/93352 Reject -- https://master.php.net/note/reject/93352 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#160228) next »