Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rationale for std::lower_bound and std::upper_bound?

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?

like image 308
Don Hatch Avatar asked May 08 '14 23:05

Don Hatch


People also ask

What is std :: lower_bound?

std::lower_boundReturns an iterator pointing to the first element in the range [first,last) which does not compare less than val . The elements are compared using operator< for the first version, and comp for the second.

What is the difference between upper bound and lower bound C++?

Upper bound and Lower bound for non increasing vector in C++ In a Vector, lower bound returns an iterator pointing to the first element in the range that does not compare the given value. Upper Bound returns an iterator pointing element in the range that smaller than given value.

Does std:: upper_ bound use binary search?

Two of my favorite algorithms in the C++ <algorithm> header are std::lower_bound and std::upper_bound , which are methods that do a binary search on sorted input.

What will the lower_bound () function return if the element you passed as an argument isn't present in the vector VECT?

lower_bound returns an iterator pointing to the first element in the range [first,last) which has a value not less than 'val'. and if the value is not present in the vector then it returns the end iterator.


2 Answers

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.)

like image 175
Brian Bi Avatar answered Sep 19 '22 19:09

Brian Bi


std::lower_bound

Returns an iterator pointing to the first element in the range [first, last) that is not less than (i.e. greater or equal to) value.

std::upper_bound

Returns an iterator pointing to the first element in the range [first, last) that is greater than value.

So by mixing both lower and upper bound you are able to exactly describe where your range begins and where it ends.

Does this make any sense??

Yes.

Example:

imagine vector

std::vector<int> data = { 1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6 };

auto lower = std::lower_bound(data.begin(), data.end(), 4);

1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6
                  // ^ lower

auto upper = std::upper_bound(data.begin(), data.end(), 4);

1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6
                           // ^ upper

std::copy(lower, upper, std::ostream_iterator<int>(std::cout, " "));

prints: 4 4 4


http://en.cppreference.com/w/cpp/algorithm/lower_bound

http://en.cppreference.com/w/cpp/algorithm/upper_bound

like image 36
4pie0 Avatar answered Sep 21 '22 19:09

4pie0