I am writing some code to find the last key whose value is no more than a given integer for PHP.
E.g.,array(0=>1,1=>2,2=>3,3=>3,4=>4). Given integer 3, I will find the key 3.(Binary Search)
And I looked for some references about binary search on the Internet.
I find this, which is to find the first key whose value is no less than a given integer for C++.
It says:
template <class _ForwardIter, class _Tp, class _Distance>
_ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last,
const _Tp& __val, _Distance*)
{
_Distance __len = 0;
distance(__first, __last, __len);
_Distance __half;
_ForwardIter __middle;
while (__len > 0) {
__half = __len >> 1;
__middle = __first;
advance(__middle, __half);
if (*__middle < __val) {
__first = __middle;
++__first;
__len = __len - __half - 1;
}
else
__len = __half; // <======this line
}
return __first;
}
Well, why using "__len = __half;" rather than "__len = __half + 1;"?
Won't the key/value ,which "_middle" refers to in each loop, be forgotten and get lost in this binary-searching-process?
I mean, it seem that the two "__len"'s won't add up to the full "__len", seems that the __middle has been skipped
PS: My PHP code for my original question is:
$cid_start = $count - 1;
$len = $count;
while($len > 0){
$half = $len >> 1;
$middle = $cid_start - $half;
if($c_index[$middle][1] > $time_start){
$cid_start = $middle - 1;
$len = len - $half - 1;
}else{
$len = $half + 1;
}
}
Will it work? Or will it err?
And how can I get a -1 or something as the result when I find nothing in array?
Just to answer the "why not …?" question: This algorithm works slightly different. If the lower bound is actually the first element, we would get a problem.
__len
would be halfed until it's 2:, and then we get an infinite loop. I.e., when
__len == 2
:This cannot happen if the assigned length is
__half
itself - then for__len == 2
we get 1, and for__len == 1
we get 0.