First of all, if you want to have a set of continuous ranges, you should simply represent them as a set that keeps only the beginning of each range.
set<int> boundaries { 0, 5, 8, 10 };
If you really want to use a structure that keeps both ends of a range, the following will allow you to search in O(log(N))
. In the case of keeping both ends, it is possible to express other than continuous ranges set, so this example intentionally omits [6, 8). If the structure keeps both ends, it is also possible to express overlapping ranges set. In that case, we would have to search for more than one range. I left that example out.
#include <algorithm>
#include <limits>
#include <numeric>
#include <set>
using namespace std;
int main()
{
set<pair<int, int>> intervals{ { 0, 5 },
{ 5, 6 },
{ 8, 10 } }; // drop {6, 8} version.
{
constexpr auto INF = numeric_limits<int>::max();
auto find = [&](const int x) {
auto next = intervals.upper_bound({ x, INF });
if (next != intervals.begin()) {
if (auto ans = prev(next); x < ans->second)
return ans;
}
return intervals.end();
};
for (int x = -1; x <= 11; ++x) {
if (auto ans = find(x); ans != intervals.end()) {
printf("%d is in [%d, %d)\n", x, ans->first, ans->second);
} else {
printf("%d is not in any range\n", x);
}
}
}
set<int> boundaries{ 0, 5, 8, 10 };
{
auto find = [&](const int x) {
auto next = boundaries.upper_bound(x);
if (next != boundaries.begin()) {
return prev(next);
}
return boundaries.end();
};
for (int x = -1; x <= 11; ++x) {
if (auto ans = find(x); ans != boundaries.end()) {
if (auto nx = next(ans); nx != boundaries.end()) {
printf("%d is in [%d, %d)\n", x, *ans, *nx);
} else {
printf("%d is in [%d, inf)\n", x, *ans);
}
} else {
printf("%d is in [-inf, %d)\n", x, *boundaries.begin());
}
}
}
}
stdout is here.
// == set<pair<int, int>>
-1 is not in any range
0 is in [0, 5)
1 is in [0, 5)
2 is in [0, 5)
3 is in [0, 5)
4 is in [0, 5)
5 is in [5, 6)
6 is not in any range
7 is not in any range
8 is in [8, 10)
9 is in [8, 10)
10 is not in any range
11 is not in any range
// == set<int>
-1 is in [-inf, 0)
0 is in [0, 5)
1 is in [0, 5)
2 is in [0, 5)
3 is in [0, 5)
4 is in [0, 5)
5 is in [5, 8)
6 is in [5, 8)
7 is in [5, 8)
8 is in [8, 10)
9 is in [8, 10)
10 is in [10, inf)
11 is in [10, inf)