STL provides binary search functions std::lower_bound and std::upper_bound, but I tend not to use them because I've been unable to remember what they do, because their contracts seem completely mystifying to me.
Just from looking at the names,
I'd guess that "lower_bound" might be short for "last lower bound",
i.e. the last element in the sorted list that is <= the given val (if any).
And similarly I'd guess "upper_bound" might be short for "first upper bound",
i.e. the first element in the sorted list that is >= the given val (if any).
But the documentation says they do something rather different from that--
something that seems to be a mixture of backwards and random, to me.
To paraphrase the doc:
- lower_bound finds the first element that's >= val
- upper_bound finds the first element that's > val
So lower_bound doesn't find a lower bound at all; it finds the first upper bound!? And upper_bound finds the first strict upper bound.
Does this make any sense?? How do you remember it?
If you have multiple elements in the range [first
, last
) whose value equals the value val
you are searching for, then the range [l
, u
) where
l = std::lower_bound(first, last, val)
u = std::upper_bound(first, last, val)
is precisely the range of elements equal to val
within the range [first
, last
). So l
and u
are the "lower bound" and "upper bound" for the equal range. It makes sense if you're accustomed to thinking in terms of half-open intervals.
(Note that std::equal_range
will return both the lower and upper bound in a pair, in a single call.)