Namespaces
Variants

std::upper_bound

Von de.cppreference.net
 
 
Algorithmenbibliothek
Eingeschränkte Algorithmen und Algorithmen auf Bereichen (C++20)
Eingeschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Nicht modifizierende Sequenzoperationen    
Batch-Operationen
(C++17)
Suchoperationen
Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Swap-Operationen
Transformationsoperationen
Erzeugungsoperationen
Entfernungsoperationen
Reihenfolgeändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
(C++11)    

Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Merge-Operationen (auf sortierten Bereichen)
Heap-Operationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikografische Vergleichsoperationen
Permutationsoperationen


 
Definiert in Header <algorithm>
template< class ForwardIt, class T >
ForwardIt upper_bound( ForwardIt first, ForwardIt last,
                       const T& value );
(1) (bis C++26)
(constexpr seit C++20)
template< class ForwardIt, class T = typename std::iterator_traits
                                         <ForwardIt>::value_type >
constexpr ForwardIt upper_bound( ForwardIt first, ForwardIt last,
                                 const T& value );
(seit C++26)
template< class ForwardIt, class T, class Compare >
ForwardIt upper_bound( ForwardIt first, ForwardIt last,
                       const T& value, Compare comp );
(2) (bis C++26)
template< class ForwardIt, class T = typename std::iterator_traits
                                         <ForwardIt>::value_type,
          class Compare >
constexpr ForwardIt upper_bound( ForwardIt first, ForwardIt last,
                                 const T& value, Compare comp );
(seit C++26)

Sucht nach dem ersten Element im partitionierten Bereich [first, last), das nach value geordnet ist.

1) Die Ordnung wird durch operator< bestimmt:

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

Falls die Elemente elem von [first, last) nicht partitioniert in Bezug auf den Ausdruck bool(value < elem) sind, ist das Verhalten undefiniert.

(bis C++20)

Äquivalent zu std::upper_bound(first, last, value, std::less{}).

(seit C++20)
2) Die Ordnung wird durch comp bestimmt:
Gibt den ersten Iterator iter in [first, last) zurück, für den bool(comp(value, *iter)) true ist, oder last, wenn kein solcher iter existiert.
Falls die Elemente elem von [first, last) nicht partitioniert in Bezug auf den Ausdruck bool(comp(value, elem)) sind, ist das Verhalten undefiniert.

Parameter

first, last - das Iteratorpaar, 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 Folgender 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 der Typen (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 T implizit in Type1 konvertiert werden kann. Der Typ Type2 muss so beschaffen sein, dass ein Objekt vom Typ ForwardIt dereferenziert und dann 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 nach 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 Iterator-Inkremente linear in N . Insbesondere sind std::map , std::multimap , std::set und std::multiset Iteratoren keine Random-Access-Iteratoren, daher sollten deren Memberfunktionen upper_bound bevorzugt verwendet werden.

Mögliche Implementierung

Siehe auch die Implementierungen in libstdc++ und libc++ .

upper_bound (1)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type>
ForwardIt upper_bound(ForwardIt first, ForwardIt last, const T& value)
{
    return std::upper_bound(first, last, value, std::less{});
}
upper_bound (2)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type,
         class Compare>
ForwardIt upper_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(value, *it))
        {
            first = ++it;
            count -= step + 1;
        } 
        else
            count = step;
    }
    return first;
}
**Anmerkung:** Die Übersetzung wurde gemäß den Anforderungen durchgeführt: - HTML-Tags und Attribute wurden nicht übersetzt - Text innerhalb der ``, `
` und `` Tags wurde nicht übersetzt  
- C++-spezifische Begriffe (wie Funktionsnamen, Typen, Schlüsselwörter) wurden beibehalten
- Nur der beschreibende Text außerhalb der Code-Blöcke wurde ins Deutsche übersetzt

Hinweise

Obwohl std::upper_bound nur erfordert, dass [ first , last ) partitioniert ist, wird dieser Algorithmus typischerweise in Fällen verwendet, in denen [ first , last ) sortiert ist, sodass die binäre Suche für jeden value gültig ist.

Für jeden Iterator iter im Bereich [ first , last ) erfordert std::upper_bound , dass value < * iter und comp ( value, * iter ) wohlgeformt sind, während std::lower_bound erfordert, dass * iter < value und comp ( * iter, value ) 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 < 7; ++i)
    {
        // Suche erstes Element, das größer als i ist
        auto upper = std::upper_bound(data.begin(), data.end(), i);
        std::cout << i << " < ";
        upper != data.end()
            ? std::cout << *upper << " an Index " << std::distance(data.begin(), upper)
            : std::cout << "nicht gefunden";
        std::cout << '\n';
    }
    std::vector<PriceInfo> prices{{100.0}, {101.5}, {102.5}, {102.5}, {107.3}};
    for (double to_find : {102.5, 110.2})
    {
        auto prc_info = std::upper_bound(prices.begin(), prices.end(), to_find,
            [](double value, const PriceInfo& info)
            {
                return value < info.price;
            });
        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}, {3, 1}};
    auto cmpz = [](CD x, CD y) { return x.real() < y.real(); };
    #ifdef __cpp_lib_algorithm_default_value_type
        auto it = std::upper_bound(nums.cbegin(), nums.cend(), {2, 0}, cmpz);
    #else
        auto it = std::upper_bound(nums.cbegin(), nums.cend(), CD{2, 0}, cmpz);
    #endif
    assert((*it == CD{3, 0}));
}

Ausgabe:

0 < 1 an Index 0
1 < 2 an Index 1
2 < 4 an Index 2
3 < 4 an Index 2
4 < 5 an Index 3
5 < 6 an Index 5
6 < nicht gefunden 
107.3 an Index 4
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 maximal log 2 (N)+1 Vergleiche waren erlaubt korrigiert zu log 2 (N)+O(1)
LWG 577 C++98 last konnte nicht zurückgegeben werden erlaubt
LWG 2150 C++98 falls ein Iterator iter in [ first , last ) existiert, sodass
bool ( comp ( value, * iter ) ) true ist, std::upper_bound
könnte jeden Iterator in [ iter , last ) zurückgeben
kein Iterator nach
iter kann zurückgegeben werden

Siehe auch

findet den Bereich von Elementen, die dem angegebenen Wert entsprechen, mittels binärer Suche
(Funktionstemplate & Algorithmus-Funktionsobjekt)
findet das erste Element, das nicht kleiner als der angegebene Wert ist, mittels binärer Suche
(Funktionstemplate & Algorithmus-Funktionsobjekt)
teilt einen Bereich von Elementen in zwei Gruppen auf
(Funktionstemplate & Algorithmus-Funktionsobjekt)
lokalisiert den Teilungspunkt eines partitionierten Bereichs
(Funktionstemplate & Algorithmus-Funktionsobjekt)
findet das erste Element, das größer als der angegebene Wert ist, mittels binärer Suche
(Algorithmus-Funktionsobjekt)
gibt einen Iterator auf das erste Element größer als der angegebene Schlüssel zurück
(öffentliche Mitgliedsfunktion von std::set<Key,Compare,Allocator>)
gibt einen Iterator auf das erste Element größer als der angegebene Schlüssel zurück
(öffentliche Mitgliedsfunktion von std::multiset<Key,Compare,Allocator>)