Code Snippets
/

std::lower_bound Recipes

std::lower_bound Recipes

`std::lower_bound` returns an iterator to the first element NOT less than a target in a sorted range, while `std::upper_bound` returns the first element strictly greater. This snippet shows how to use both for sorted-insertion, range-counting, and predicate-based binary search via the comparator overload. All run in O(log n) on random-access iterators.

C++
Medium
3 snippets
cpp-algorithms-stl
binary-search
binary-search-templates

493 views

14

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> v = {1, 2, 4, 4, 4, 7, 9};

    // lower_bound: first element NOT less than target. For 4: index 2.
    auto lo = std::lower_bound(v.begin(), v.end(), 4);
    // upper_bound: first element strictly greater than target. For 4: index 5.
    auto hi = std::upper_bound(v.begin(), v.end(), 4);

    std::cout << "lower idx=" << (lo - v.begin())
              << " upper idx=" << (hi - v.begin()) << "\n";
    std::cout << "count of 4 = " << (hi - lo) << "\n";

    // Containment test:
    bool has5 = (std::lower_bound(v.begin(), v.end(), 5) != v.end()) &&
                *std::lower_bound(v.begin(), v.end(), 5) == 5;
    std::cout << "has 5? " << (has5 ? "yes" : "no") << "\n";
    return 0;
}

Both functions assume the input range is already sorted (or at least partitioned by the predicate); the result on an unsorted range is unspecified. The half-open interval [lower_bound, upper_bound) is exactly the run of elements equal to the target, so upper - lower gives the count of duplicates in O(log n). For a contains-check, compare *lower_bound with the target after verifying the iterator is not at end(). std::binary_search exists for this case but only returns a bool; lower_bound is more useful because you keep the iterator for further work.