Namespaces
Variants

std::ranges:: lower_bound

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
Défini dans l'en-tête <algorithm>
Signature d'appel
(1)
template < std:: forward_iterator I, std:: sentinel_for < I > S,

class T, class Proj = std:: identity ,
std:: indirect_strict_weak_order
< const T * , std :: projected < I, Proj >> Comp = ranges:: less >
constexpr I lower_bound ( I first, S last, const T & value,

Comp comp = { } , Proj proj = { } ) ;
(depuis C++20)
(jusqu'à C++26)
template < std:: forward_iterator I, std:: sentinel_for < I > S,

class Proj = std:: identity ,
class T = std :: projected_value_t < I, Proj > ,
std:: indirect_strict_weak_order
< const T * , std :: projected < I, Proj >> Comp = ranges:: less >
constexpr I lower_bound ( I first, S last, const T & value,

Comp comp = { } , Proj proj = { } ) ;
(depuis C++26)
(2)
template < ranges:: forward_range R,

class T, class Proj = std:: identity ,
std:: indirect_strict_weak_order
< const T * , std :: projected < ranges:: iterator_t < R > ,
Proj >> Comp = ranges:: less >
constexpr ranges:: borrowed_iterator_t < R >

lower_bound ( R && r, const T & value, Comp comp = { } , Proj proj = { } ) ;
(depuis C++20)
(jusqu'à C++26)
template < ranges:: forward_range R,

class Proj = std:: identity ,
class T = std :: projected_value_t < ranges:: iterator_t < R > , Proj > ,
std:: indirect_strict_weak_order
< const T * , std :: projected < ranges:: iterator_t < R > ,
Proj >> Comp = ranges:: less >
constexpr ranges:: borrowed_iterator_t < R >

lower_bound ( R && r, const T & value, Comp comp = { } , Proj proj = { } ) ;
(depuis C++26)
1) Renvoie un itérateur pointant vers le premier élément de l'intervalle [ first , last ) qui n'est pas inférieur à (c'est-à-dire supérieur ou égal à) value , ou last si aucun tel élément n'est trouvé. L'intervalle [ first , last ) doit être partitionné par rapport à l'expression std:: invoke ( comp, std:: invoke ( proj, element ) , value ) , c'est-à-dire que tous les éléments pour lesquels l'expression est true doivent précéder tous les éléments pour lesquels l'expression est false . Un intervalle entièrement trié satisfait ce critère.
2) Identique à (1) , mais utilise r comme plage source, comme si on utilisait ranges:: begin ( r ) comme first et ranges:: end ( r ) comme last .

Les entités de type fonction décrites sur cette page sont des objets fonction d'algorithme (informellement appelés niebloids ), c'est-à-dire :

Table des matières

Paramètres

first, last - la paire itérateur-sentinelle définissant la plage partiellement ordonnée des éléments à examiner
r - la plage partiellement ordonnée à examiner
value - valeur à comparer aux éléments projetés
comp - prédicat de comparaison à appliquer aux éléments projetés
proj - projection à appliquer aux éléments

Valeur de retour

Itérateur pointant vers le premier élément qui est non inférieur à value , ou last si aucun tel élément n'est trouvé.

Complexité

Le nombre de comparaisons et d'applications de la projection effectuées est logarithmique par rapport à la distance entre first et last (au plus log 2 (last - first) + O(1) comparaisons et applications de la projection). Cependant, pour un itérateur qui ne modélise pas random_access_iterator , le nombre d'incrémentations d'itérateur est linéaire.

Notes

Sur une plage entièrement triée (ou plus généralement, partiellement ordonnée par rapport à value ) après projection, std::ranges::lower_bound implémente l'algorithme de recherche binaire. Par conséquent, std::ranges::binary_search peut être implémentée en l'utilisant.

Macro de test de fonctionnalité Valeur Std Fonctionnalité
__cpp_lib_algorithm_default_value_type 202403 (C++26) Initialisation par liste pour les algorithmes ( 1,2 )

Implémentation possible

struct lower_bound_fn
{
    template<std::forward_iterator I, std::sentinel_for<I> S, class Proj = std::identity,
             class T = std::projected_value_t<I, Proj>,
             std::indirect_strict_weak_order
                 <const T*, std::projected<I, Proj>> Comp = ranges::less>
    constexpr I operator()(I first, S last, const T& value,
                           Comp comp = {}, Proj proj = {}) const
    {
        I it;
        std::iter_difference_t<I> count, step;
        count = std::ranges::distance(first, last);
        while (count > 0)
        {
            it = first;
            step = count / 2;
            ranges::advance(it, step, last);
            if (comp(std::invoke(proj, *it), value))
            {
                first = ++it;
                count -= step + 1;
            }
            else
                count = step;
        }
        return first;
    }
    template<ranges::forward_range R, class Proj = std::identity,
             class T = std::projected_value_t<ranges::iterator_t<R>, Proj>,
             std::indirect_strict_weak_order
                 <const T*, std::projected<ranges::iterator_t<R>,
                                           Proj>> Comp = ranges::less>
    constexpr ranges::borrowed_iterator_t<R>
        operator()(R&& r, const T& value, Comp comp = {}, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), value,
                       std::ref(comp), std::ref(proj));
    }
};
inline constexpr lower_bound_fn lower_bound;

Exemple

#include <algorithm>
#include <cassert>
#include <complex>
#include <iostream>
#include <iterator>
#include <vector>
namespace ranges = std::ranges;
template<std::forward_iterator I, std::sentinel_for<I> S, class T,
         class Proj = std::identity,
         std::indirect_strict_weak_order
             <const T*, std::projected<I, Proj>> Comp = ranges::less>
constexpr I binary_find(I first, S last, const T& value, Comp comp = {}, Proj proj = {})
{
    first = ranges::lower_bound(first, last, value, comp, proj);
    return first != last && !comp(value, proj(*first)) ? first : last;
}
int main()
{
    std::vector data{1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5};
    //                                 ^^^^^^^^^^
    auto lower = ranges::lower_bound(data, 4);
    auto upper = ranges::upper_bound(data, 4);
    std::cout << "found a range [" << ranges::distance(data.cbegin(), lower)
              << ", " << ranges::distance(data.cbegin(), upper) << ") = { ";
    ranges::copy(lower, upper, std::ostream_iterator<int>(std::cout, " "));
    std::cout << "}\n";
    // recherche binaire classique, retournant une valeur uniquement si elle est présente
    data = {1, 2, 4, 8, 16};
    //               ^
    auto it = binary_find(data.cbegin(), data.cend(), 8); // '5' retournerait end()
    if (it != data.cend())
        std::cout << *it << " trouvé à l'index " << ranges::distance(data.cbegin(), it);
    using CD = std::complex<double>;
    std::vector<CD> nums{{1, 0}, {2, 2}, {2, 1}, {3, 0}};
    auto cmpz = [](CD x, CD y) { return x.real() < y.real(); };
    #ifdef __cpp_lib_algorithm_default_value_type
        auto it2 = ranges::lower_bound(nums, {2, 0}, cmpz);
    #else
        auto it2 = ranges::lower_bound(nums, CD{2, 0}, cmpz);
    #endif
    assert((*it2 == CD{2, 2}));
}

Sortie :

found a range [6, 10) = { 4 4 4 4 }
8 found at index 3

Voir aussi

retourne la plage d'éléments correspondant à une clé spécifique
(objet fonction algorithme)
divise une plage d'éléments en deux groupes
(objet fonction algorithme)
localise le point de partition d'une plage partitionnée
(objet fonction algorithme)
retourne un itérateur vers le premier élément supérieur à une certaine valeur
(objet fonction algorithme)
retourne un itérateur vers le premier élément non inférieur à la valeur donnée
(modèle de fonction)