upper_bound in C++ (original) (raw)

upper_bound is a Standard Template Library (STL) function used to find the first element that is strictly greater than a given value in a sorted range. It is commonly used for efficient searching and range queries in sorted containers.

**Example: Basic Usage with Vector

C++ `

#include #include #include using namespace std;

int main() { vector v = {10, 20, 30, 40, 50};

// Finding upper bound for value 30 in vector v
cout << *upper_bound(v.begin(), v.end(), 30);

return 0;

}

`

**Explanation:

Syntax

iterator upper_bound(iterator first, iterator last, const T& value);

Parameters

Return Value

**Note: The behavior of std::upper_bound() is undefined if the range is not sorted

The below examples demonstrate some of its common uses.

**Example 1: Find Upper Bound in an Array

C++ `

#include #include #include using namespace std;

int main() { int arr[5] = {10, 20, 30, 40, 50}; int n = sizeof(arr) / sizeof(arr[0]);

// Finding upper bound for value 30 in array arr
cout << *upper_bound(arr, arr + n, 30);

return 0;

}

`

**Explanation: This code uses upper_bound() to find and print the first element in the sorted array that is strictly greater than 30, which is 40.

**Example 2: Use upper_bound() with Custom Comparator

C++ `

#include #include #include using namespace std;

bool comp(const string &a, const string &b) { return lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), [](char c1, char c2) { return tolower(c1) < tolower(c2); }); }

int main() { vector v = {"Apple", "banana", "Cherry", "date", "Elderberry"};

// Finding upper bound of "Avocado"
auto ub = upper_bound(v.begin(), v.end(), "Avocado", comp);

if (ub != v.end())
    cout << *ub;
else
    cout << "Upper bound not found!";

return 0;

}

`

**Explanation: We need to use the custom comparator function to perform the case insensitive search as the default comparator treats the uppercase and lowercase differently.

**Example 3: Check for an Element in a Sorted Vector

C++ `

#include #include #include using namespace std;

int main() { vector v = {10, 20, 30, 40, 50}; int val = 40;

// Finding the upper bound
auto it = upper_bound(v.begin(), v.end(), val);

// Chekcing if val exists or not
if (it != v.begin() && *(--it) == val)
    cout << val << " is found.";
else
    cout << val << " is NOT found.";

return 0;

}

`

**Explanation: upper_bound() returns the iterator just after the matching value; to check if the value exists, decrement the iterator and compare.

**Example 4: Count Elements Smaller and Larger than a Value

C++ `

#include #include #include using namespace std;

int main() { vector v = {10, 20, 30, 40, 50}; int val = 30;

// Finding the upper bound of val in v
auto ub = upper_bound(v.begin(), v.end(), val);

// Finding the number of smaller elements
cout << "No. of Smaller Elements: " << ub - v.begin() << endl;

// Finding the number of larger elements
cout << "No. of Larger Elements: " << v.end() - ub;

return 0;

}

`

Output

No. of Smaller Elements: 3 No. of Larger Elements: 2

**Explanation: Counts elements based on the position returned by upper_bound().

Finding Upper Bound in a Set

It is recommended to use set::upper_bound() for set as sets do not have random access to its elements. So, the upper_bound() function have to increment it sequentially to find the middle element (part of binary search algorithm) each time leading to increased time complexity.

C++ `

#include #include #include using namespace std;

int main(){

set<int> s = {1, 2, 4, 4, 6, 8};

// Recommended: O(log n)
auto it1 = s.upper_bound(4);

if (it1 != s.end())
    cout << "set::upper_bound -> " << *it1 << endl;
else
    cout << "set::upper_bound -> Not found" << endl;

// Not recommended: O(n) for set
auto it2 = upper_bound(s.begin(), s.end(), 4);

if (it2 != s.end())
    cout << "std::upper_bound -> " << *it2 << endl;
else
    cout << "std::upper_bound -> Not found" << endl;

return 0;

}

`

Output

set::upper_bound -> 6 std::upper_bound -> 6

**Explanation: