Difference between std::set::upper_bound and std::upper_bound in C++
Prerequisites: Random-access Iterators, Bidirectional Iterators
Sets are a type of associative container in which each element has to be unique because the value of the element identifies it. The value of the element cannot be modified once it is added to the set, though it is possible to remove and add the modified value of that element.
Functions associated with Set:
- begin(): Returns an iterator to the first element in the set.
- end(): Returns an iterator to the theoretical element that follows the last element in the set.
- size(): Returns the number of elements in the set.
- max_size(): Returns the maximum number of elements that the set can hold.
- empty(): Returns whether the set is empty.
This article focuses upon the difference between std::set::upper_bound and std::upper_bound in C++.
std::upper_bound() in C++
The upper_bound() method in C++ is used to return an iterator pointing to the first element in the range [first, last) which has a value greater than the given value.
std::set::upper_bound() in C++
The set::upper_bound() is a built-in function in C++ STL that returns an iterator pointing to the element in the container which is just greater than the value ‘x’ passed as a parameter. If the key passed in the parameter exceeds the maximum value in the container, then the iterator returned points to the last element in the set container.
std::upper_bound() vs std::set::upper_bound()
Below are some of the differences between std::upper_bound() and std::set::upper_bound().
Sr. No. | std::upper_bound() | std::set::upper_bound() |
1 | Syntax- std::upper_bound(ForwardIterator first, ForwardIterator last, const T& val). |
Syntax- std::upper_bound(const value_type& val). |
2 | The std::upper_bound has Random Access Iterators and Non Random Access Iterators. | The std::set::upper optimizes_bound has Bidirectional Iterators. |
3 | This function optimizes the number of comparisons which is efficient for Random Access Iterators. | This function optimizes the number of comparisons using Bidirectional Iterators. |
4 | The running time complexity is O(log2N) for random-access iterators but for non-random-access iterators, it is O(N). | The running time complexity is always O(log2N) due to its Binary Search Tree implementation. |
In the below examples, we have illustrated CPU execution time taken by both functions. Generally, std::set::upper_bound() method is preferred overstd::upper_bound().
Example: std::upper_bound()
Below is the C++ program to illustrate std::upper_bound() function.
C++
// C++ program to illustrate // std::set::upper_bound #include <bits/stdc++.h> #include <sys/time.h> using namespace std; // Function whose time is to // be measured void myFunction() { // Initialise the set set< int > s; // Insert element in the set for ( int i = 0; i < 10; i++) { s.insert(i); } // Use upper_bound() function // to find 5 set< int >::iterator it; it = upper_bound(s.begin(), s.end(), 5); } // Driver Code int main() { // Use function gettimeofday() // can get the time struct timeval start, end; // Start timer gettimeofday(&start, NULL); // unsync the I/O of C and C++. ios_base::sync_with_stdio( false ); // Function Call myFunction(); // Stop timer gettimeofday(&end, NULL); // Calculating total time taken // by the program. double totalTime; totalTime = (end.tv_sec - start.tv_sec) * 1e6; totalTime = (totalTime + (end.tv_usec - start.tv_usec)) * 1e-6; cout << "Time taken by the program is : " << fixed << totalTime << setprecision(6); cout << " sec" << endl; return 0; } |
Time taken by the program is : 0.000056 sec
Example: std::set::upper_bound()
Below is the C++ program to illustrate of std::set::upper_bound() function.
C++
// C++ program to illustrate // std::upper_bound #include <bits/stdc++.h> #include <sys/time.h> using namespace std; // Function whose time is to // be measured void myFunction() { // Initialise the set set< int > s; // Insert element in the set for ( int i = 0; i < 10; i++) { s.insert(i); } // Use set::upper_bound() function // to find 5 set< int >::iterator it; it = s.upper_bound(5); } // Driver Code int main() { // Use function gettimeofday() // can get the time struct timeval start, end; // Start timer gettimeofday(&start, NULL); // unsync the I/O of C and C++. ios_base::sync_with_stdio( false ); myFunction(); // Stop timer gettimeofday(&end, NULL); // Calculating total time taken // by the program. double totalTime; totalTime = (end.tv_sec - start.tv_sec) * 1e6; totalTime = (totalTime + (end.tv_usec - start.tv_usec)) * 1e-6; cout << "Time taken by program is : " << fixed << totalTime << setprecision(6); cout << " sec" << endl; return 0; } |
Time taken by program is : 0.000043 sec