Namespaces
Variants

std:: 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)
lower_bound
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
Definiert in Header <algorithm>
(1)
template < class ForwardIt, class T >

ForwardIt lower_bound ( ForwardIt first, ForwardIt last,

const T & value ) ;
(constexpr seit C++20)
(bis C++26)
template < class ForwardIt, class T = typename std:: iterator_traits

< ForwardIt > :: value_type >
constexpr ForwardIt lower_bound ( ForwardIt first, ForwardIt last,

const T & value ) ;
(seit C++26)
(2)
template < class ForwardIt, class T, class Compare >

ForwardIt lower_bound ( ForwardIt first, ForwardIt last,

const T & value, Compare comp ) ;
(constexpr seit C++20)
(bis C++26)
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 ) ;
(seit C++26)

Durchsucht den partitionierten Bereich [ first , last ) nach dem ersten Element, das nicht vor value geordnet ist.

1) Die Reihenfolge wird durch operator < bestimmt:

Gibt den ersten Iterator iter in [ first , last ) zurück, für den bool ( * iter < value ) false ist, oder last falls kein solcher iter existiert.

Wenn die Elemente elem von [ first , last ) nicht bezüglich des Ausdrucks bool ( elem < value ) partitioniert sind, ist das Verhalten undefiniert.

(bis C++20)

Entspricht std :: lower_bound ( first, last, value, std:: less { } ) .

(seit C++20)
2) Die Reihenfolge wird durch comp bestimmt:
Gibt den ersten Iterator iter in [ first , last ) zurück, für den bool ( comp ( * iter, value ) ) den Wert false ergibt, oder last falls kein solcher iter existiert.
Wenn die Elemente elem von [ first , last ) nicht bezüglich des Ausdrucks bool ( comp ( elem, value ) ) partitioniert sind, ist das Verhalten undefiniert.

Inhaltsverzeichnis

Parameter

first, last - das Paar von Iteratoren, das den partitionierten Bereich der zu untersuchenden Elemente definiert
value - Wert, mit dem die Elemente verglichen werden
comp - binäres Prädikat, das ​ true zurückgibt, wenn das erste Argument vor dem zweiten geordnet ist.

Die Signatur der Prädikatfunktion sollte äquivalent zu Folgendem sein:

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

Obwohl die Signatur nicht const & benötigt, darf die Funktion die übergebenen Objekte nicht modifizieren und muss alle Werte des Typs (möglicherweise const) Type1 und Type2 unabhängig von der Wertkategorie akzeptieren können (daher ist Type1 & nicht erlaubt , ebenso wenig wie Type1 , es sei denn, für Type1 ist eine Verschiebung äquivalent zu einer Kopie (seit C++11) ).
Der Typ Type1 muss so beschaffen sein, dass ein Objekt vom Typ ForwardIt dereferenziert und dann implizit in Type1 konvertiert werden kann. Der Typ Type2 muss so beschaffen sein, dass ein Objekt vom Typ T implizit in Type2 konvertiert werden kann. ​

Typanforderungen
-
ForwardIt muss die Anforderungen von LegacyForwardIterator erfüllen.
-
Compare muss die Anforderungen von BinaryPredicate erfüllen. Es muss nicht Compare erfüllen.

Rückgabewert

Iterator zum ersten Element des Bereichs [ first , last ) der nicht vor value geordnet ist, oder last falls kein solches Element gefunden wird.

Komplexität

Gegeben N als std:: distance ( first, last ) :

1) Höchstens log 2 (N)+O(1) Vergleiche mit value unter Verwendung von operator < (bis C++20) std:: less { } (seit C++20) .
2) Höchstens log 2 (N)+O(1) Anwendungen des Comparators comp .

Wenn jedoch ForwardIt kein LegacyRandomAccessIterator ist, ist die Anzahl der Iteratorinkremente linear in N . Insbesondere sind std::map , std::multimap , std::set - und std::multiset -Iteratoren keine Random-Access-Iteratoren, daher sollten deren Memberfunktionen lower_bound bevorzugt werden.

Mögliche Implementierung

Siehe auch die Implementierungen in libstdc++ und 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;
}

Hinweise

Obwohl std::lower_bound nur erfordert, dass [ first , last ) partitioniert ist, wird dieser Algorithmus üblicherweise in dem Fall verwendet, wo [ first , last ) sortiert ist, sodass die binäre Suche für jeden value gültig ist.

Im Gegensatz zu std::binary_search erfordert std::lower_bound nicht, dass operator < oder comp asymmetrisch sind (d.h., a < b und b < a immer unterschiedliche Ergebnisse liefern). Tatsächlich erfordert es nicht einmal, dass value < * iter oder comp ( value, * iter ) für irgendeinen Iterator iter in [ first , last ) wohlgeformt sind.

Feature-Test Makro Wert Std Feature
__cpp_lib_algorithm_default_value_type 202403 (C++26) Listeninitialisierung für Algorithmen ( 1,2 )

Beispiel

#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)
    {
        // Suche nach dem ersten Element x, für das i ≤ x gilt
        auto lower = std::lower_bound(data.begin(), data.end(), i);
        std::cout << i << " ≤ ";
        lower != data.end()
            ? std::cout << *lower << " an Index " << std::distance(data.begin(), lower)
            : std::cout << "nicht gefunden";
        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 << " an Index " << prc_info - prices.begin()
            : std::cout << to_find << " nicht gefunden";
        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}));
}

Ausgabe:

0 ≤ 1 an Index 0
1 ≤ 1 an Index 0
2 ≤ 2 an Index 1
3 ≤ 4 an Index 2
4 ≤ 4 an Index 2
5 ≤ 5 an Index 3
6 ≤ 6 an Index 5
7 ≤ nicht gefunden
102.5 an Index 2
110.2 nicht gefunden

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 270 C++98 Compare musste Compare erfüllen und T musste
LessThanComparable sein (strikte schwache Ordnung erforderlich)
nur Partitionierung erforderlich;
heterogene Vergleiche erlaubt
LWG 384 C++98 höchstens log(N)+1 Vergleiche waren erlaubt korrigiert zu log 2 (N)+1
LWG 2150 C++98 falls ein Iterator iter in [ first , last ) existiert, sodass
bool ( comp ( * iter, value ) ) false ist, std::lower_bound
könnte jeden Iterator in [ iter , last ) zurückgeben
kein Iterator nach
iter kann zurückgegeben werden

Siehe auch

gibt den Bereich der Elemente zurück, die einem bestimmten Schlüssel entsprechen
(Funktions-Template)
unterteilt einen Elementbereich in zwei Gruppen
(Funktions-Template)
lokalisiert den Partitionierungspunkt eines partitionierten Bereichs
(Funktions-Template)
gibt einen Iterator zum ersten Element zurück, das größer als ein bestimmter Wert ist
(Funktions-Template)
gibt einen Iterator zum ersten Element zurück, das nicht kleiner als der gegebene Schlüssel ist
(öffentliche Elementfunktion von std::set<Key,Compare,Allocator> )
gibt einen Iterator zum ersten Element zurück, das nicht kleiner als der gegebene Schlüssel ist
(öffentliche Elementfunktion von std::multiset<Key,Compare,Allocator> )
gibt einen Iterator zum ersten Element zurück, das nicht kleiner als der gegebene Wert ist
(Algorithmus-Funktionsobjekt)