I would like to understand the impact of the comparison function (< or <=) on both lower_bound and upper_bound functions.
Consider this program:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v = {0, 1, 2, 3, 3, 3, 3, 3, 4, 5, 6, 7};
auto it1 = lower_bound(v.begin(), v.end(), 3, [](int a, int b) {return a < b;});
auto it2 = lower_bound(v.begin(), v.end(), 3, [](int a, int b) {return a <= b;});
auto it3 = upper_bound(v.begin(), v.end(), 3, [](int a, int b) {return a < b;});
auto it4 = upper_bound(v.begin(), v.end(), 3, [](int a, int b) {return a <= b;});
cout << distance(v.begin(), it1) << endl;
cout << distance(v.begin(), it2) << endl;
cout << distance(v.begin(), it3) << endl;
cout << distance(v.begin(), it4) << endl;
return 0;
}
this result is:
3
8
8
3
Could anybody explain this results?
Could we say that lower_bound with < is equivalent to upper_bound with <= all the time?
Same question for (lower_bound, <=) and (upper_bound, <).
Could anybody explain this results?
I'll try by describing what they do and by showing a table:
std::lower_bound - Returns the first iterator iter in [first, last) where bool(comp(*iter, value)) is false.std::upper_bound - Returns the first iterator iter in [first, last) where bool(comp(value, *iter)) is true.| alg. | 0 | 1 | 2 | 3 | 3 | 3 | 3 | 3 | 4 | 5 | 6 | 7 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
lower: *iter < 3 |
T | T | T | F | 3 < 3 first false |
||||||||
lower: *iter <= 3 |
T | T | T | T | T | T | T | T | F | 4 <= 3 first false |
|||
upper: 3 < *iter |
F | F | F | F | F | F | F | F | T | 3 < 4 first true |
|||
upper: 3 <= *iter |
F | F | F | T | 3 <= 3 first true |
Could we say that
lower_boundwith<is equivalent to upper_bound with<=all the time? [and vice versa]
As long as the range is partitioned according to bool(comp(elem, value)) (lower_bound) and bool(comp(value, elem)) (upper_bound) using both < and <=, as it is in your case, then yes. As you can hopefully see above, *iter < 3 will then find the first false when 3 <= *iter finds the first true and vice versa. You get:
*iter < value == !(value <= *iter) and *iter <= value == !(value < *iter)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With