Namespaces
Variants

std::lower_bound

Depuis fr.cppreference.net
 
 
Bibliothèque d'algorithmes
Algorithmes contraints et algorithmes sur les plages (C++20)
Algorithmes contraints, p. ex. ranges::copy, ranges::sort, ...
Opérations de séquence non modificatrices    
Opérations par lots
(C++17)
Opérations de recherche
Opérations de séquence modificatrices
Opérations de copie
(C++11)
(C++11)
Opérations d'échange
Opérations de transformation
Opérations de génération
Opérations de suppression
Opérations de changement d'ordre
(jusqu'à C++17)(C++11)
(C++20)(C++20)
Opérations d'échantillonnage
(C++17)

Tri et opérations associées
Opérations de partitionnement
(C++11)    

Opérations de tri
Opérations de recherche binaire
(sur les plages partitionnées)
Opérations ensemblistes (sur les plages triées)
Opérations de fusion (sur les plages triées)
Opérations sur le tas
Opérations de minimum/maximum
(C++11)
(C++17)
Opérations de comparaison lexicographique
Opérations de permutation


 
Défini dans l'en-tête <algorithm>
template< class ForwardIt, class T >
ForwardIt lower_bound( ForwardIt first, ForwardIt last,
                       const T& value );
(1) (jusqu'à C++26)
(constexpr depuis C++20)
template< class ForwardIt, class T = typename std::iterator_traits
                                         <ForwardIt>::value_type >
constexpr ForwardIt lower_bound( ForwardIt first, ForwardIt last,
                                 const T& value );
(depuis C++26)
template< class ForwardIt, class T, class Compare >
ForwardIt lower_bound( ForwardIt first, ForwardIt last,
                       const T& value, Compare comp );
(2) (jusqu'à C++26)
(constexpr depuis C++20)
template< class ForwardIt, class T = typename std::iterator_traits
                                         <ForwardIt>::value_type,
          class Compare >
constexpr ForwardIt lower_bound( ForwardIt first, ForwardIt last,
                                 const T& value, Compare comp );
(depuis C++26)

Recherche le premier élément dans la plage partitionnée [firstlast) qui n'est pas ordonné avant value.

1) L'ordre est déterminé par operator<:

Retourne le premier itérateur iter dans [firstlast)bool(*iter < value) est false, ou last si aucun iter de ce type n'existe.

Si les éléments elem de [firstlast) ne sont pas partitionnés par rapport à l'expression bool(elem < value), le comportement est indéfini.

(jusqu'à C++20)

Équivalent à std::lower_bound(first, last, value, std::less{}).

(depuis C++20)
2) L'ordre est déterminé par comp:
Retourne le premier itérateur iter dans [firstlast)bool(comp(*iter, value)) est false, ou last si aucun iter de ce type n'existe.
Si les éléments elem de [firstlast) ne sont pas partitionnés par rapport à l'expression bool(comp(elem, value)), le comportement est indéfini.

Paramètres

premier, dernier - la paire d'itérateurs définissant la plage partitionnée d'éléments à examiner
valeur - valeur à laquelle comparer les éléments
comp - prédicat binaire qui retourne true si le premier argument est ordonné avant le second.

La signature de la fonction de prédicat doit être équivalente à ce qui suit :

bool pred(const Type1 &a, const Type2 &b);

Bien que la signature n'ait pas besoin d'avoir const &, la fonction ne doit pas modifier les objets qui lui sont passés et doit pouvoir accepter toutes les valeurs de type (possiblement const) Type1 et Type2 indépendamment de la catégorie de valeur (ainsi, Type1 & n'est pas autorisé, ni Type1 sauf si pour Type1 un déplacement est équivalent à une copie(depuis C++11)).
Le type Type1 doit être tel qu'un objet de type ForwardIt puisse être déréférencé puis implicitement converti en Type1. Le type Type2 doit être tel qu'un objet de type T puisse être implicitement converti en Type2. ​

Exigences de type
-
ForwardIt doit satisfaire les exigences de LegacyForwardIterator.
-
Compare doit satisfaire les exigences de BinaryPredicate. Il n'est pas nécessaire qu'il satisfasse Compare.

Valeur de retour

Itérateur pointant vers le premier élément de la plage [firstlast) qui n'est pas ordonné avant value, ou last si aucun élément de ce type n'est trouvé.

Complexité

Soit N tel que std::distance(first, last):

1) Au plus log2(N)+O(1) comparaisons avec value utilisant operator<(jusqu'à C++20)std::less{}(depuis C++20).
2) Au plus log2(N)+O(1) applications du comparateur comp.

Cependant, si ForwardIt n'est pas un LegacyRandomAccessIterator, le nombre d'incréments d'itérateur est linéaire en N. Notamment, les itérateurs de std::map, std::multimap, std::set, et std::multiset ne sont pas à accès aléatoire, et donc leurs fonctions membres lower_bound doivent être préférées.

Implémentation possible

Voir aussi les implémentations dans libstdc++ et libc++.

lower_bound (1)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type>
ForwardIt lower_bound(ForwardIt first, ForwardIt last, const T& value)
{
    return std::lower_bound(first, last, value, std::less{});
}
lower_bound (2)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type,
         class Compare>
ForwardIt lower_bound(ForwardIt first, ForwardIt last, const T& value, Compare comp)
{
    ForwardIt it;
    typename std::iterator_traits<ForwardIt>::difference_type count, step;
    count = std::distance(first, last);
    
    while (count > 0)
    {
        it = first;
        step = count / 2;
        std::advance(it, step);
        
        if (comp(*it, value))
        {
            first = ++it;
            count -= step + 1;
        }
        else
            count = step;
    }
    
    return first;
}

Notes

Bien que std::lower_bound ne nécessite que [firstlast) soit partitionnée, cet algorithme est généralement utilisé lorsque [firstlast) est triée, afin que la recherche binaire soit valide pour n'importe quel value.

Contrairement à std::binary_search, std::lower_bound n'exige pas que operator< ou comp soit asymétrique (c'est-à-dire que a < b et b < a aient toujours des résultats différents). En fait, il n'exige même pas que value < *iter ou comp(value, *iter) soit bien formé pour tout itérateur iter dans [firstlast).

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)

Exemple

#include <algorithm>
#include <cassert>
#include <complex>
#include <iostream>
#include <vector>

struct PriceInfo { double price; };

int main()
{
    const std::vector<int> data{1, 2, 4, 5, 5, 6};
    
    for (int i = 0; i < 8; ++i)
    {
        // Search for first element x such that i ≤ x
        auto lower = std::lower_bound(data.begin(), data.end(), i);
        
        std::cout << i << " ≤ ";
        lower != data.end()
            ? std::cout << *lower << " at index " << std::distance(data.begin(), lower)
            : std::cout << "not found";
        std::cout << '\n';
    }
    
    std::vector<PriceInfo> prices{{100.0}, {101.5}, {102.5}, {102.5}, {107.3}};
    
    for (const double to_find : {102.5, 110.2})
    {
        auto prc_info = std::lower_bound(prices.begin(), prices.end(), to_find,
            [](const PriceInfo& info, double value)
            {
                return info.price < value;
            });
        
        prc_info != prices.end()
            ? std::cout << prc_info->price << " at index " << prc_info - prices.begin()
            : std::cout << to_find << " not found";
        std::cout << '\n';
    }

    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 it = std::lower_bound(nums.cbegin(), nums.cend(), {2, 0}, cmpz);
    #else
        auto it = std::lower_bound(nums.cbegin(), nums.cend(), CD{2, 0}, cmpz);
    #endif
    assert((*it == CD{2, 2}));
}

Sortie :

0 ≤ 1 at index 0
1 ≤ 1 at index 0
2 ≤ 2 at index 1
3 ≤ 4 at index 2
4 ≤ 4 at index 2
5 ≤ 5 at index 3
6 ≤ 6 at index 5
7 ≤ not found
102.5 at index 2
110.2 not found

Rapports de défauts

Les rapports de défauts suivants, modifiant le comportement, ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement publié Comportement correct
LWG 270 C++98 Compare était requis de satisfaire Compare et T était requis
d'être LessThanComparable (ordre faible strict requis)
seul un partitionnement est requis ;
comparaisons hétérogènes permises
LWG 384 C++98 au plus log(N)+1 comparaisons étaient autorisées corrigé en log2(N)+1
LWG 2150 C++98 si un itérateur iter existe dans [firstlast) tel que
bool(comp(*iter, value)) est false, std::lower_bound
pouvait retourner n'importe quel itérateur dans [iterlast)
aucun itérateur après
iter ne peut être retourné

Voir aussi

trouve la plage d'éléments correspondant à la valeur donnée en utilisant la recherche binaire
(modèle de fonction & objet fonction algorithme)
divise une plage d'éléments en deux groupes
(modèle de fonction & objet fonction algorithme)
localise le point de partition d'une plage partitionnée
(modèle de fonction & objet fonction algorithme)
trouve le premier élément plus grand que la valeur donnée en utilisant la recherche binaire
(modèle de fonction & objet fonction algorithme)
retourne un itérateur vers le premier élément non inférieur à la clé donnée
(fonction membre publique de std::set<Key,Compare,Allocator>)
retourne un itérateur vers le premier élément non inférieur à la clé donnée
(fonction membre publique de std::multiset<Key,Compare,Allocator>)
trouve le premier élément non inférieur à la valeur donnée en utilisant la recherche binaire
(objet fonction algorithme)