Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to check whether a set has element(s) in certain range in C++

I need to check if a std::set contains element/elements in a range. For example, if the set is a set<int> {1, 2, 4, 7, 8}, and given an int interval [3, 5] (inclusive with both endpoints), I need to know if it has elements in the set. In this case, return true. But if the interval is [5, 6], return false. The interval may be [4, 4], but not [5, 3].

Looks like I can use set::lower_bound, but I am not sure whether this is the correct approach. I also want to keep the complexity as low as possible. I believe using lower_bound is logarithmic, correct?

like image 872
Qiang Li Avatar asked Jan 25 '12 02:01

Qiang Li


2 Answers

You can use lower_bound and upper_bound together. Your example of testing for elements between 3 and 5, inclusive, could be written as follows:

bool contains_elements_in_range = s.lower_bound(3) != s.upper_bound(5);

You can make the range inclusive or exclusive on either end by switching which function you are using (upper_bound or lower_bound):

s.upper_bound(2) != s.upper_bound(5); // Tests (2, 5]
s.lower_bound(3) != s.lower_bound(6); // Tests [3, 6)
s.upper_bound(2) != s.lower_bound(6); // Tests (2, 6)

Logarithmic time is the best you can achieve for this, since the set is sorted and you need to find an element in the sorted range, which requires a dichotomic search.

like image 179
James McNellis Avatar answered Oct 22 '22 11:10

James McNellis


If you're certain that you're going to use a std::set, then I agree that its lower_bound method is the way to go. As you say, it will have logarithmic time complexity.

But depending what you're trying to do, your program's overall performance might be better if you use a sorted std::vector and the standalone std::lower_bound algorithm (std::lower_bound(v.begin(), v.end(), 3)). This is also logarithmic, but with a lower constant. (The downside, of course, is that inserting elements into a std::vector, and keeping it sorted, is usually much more expensive than inserting elements into a std::set.)

like image 37
ruakh Avatar answered Oct 22 '22 09:10

ruakh