Namespaces
Variants

std::binary_search

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    
Stapeloperationen
(C++17)
Suchoperationen
Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Reihenfolgeänderungsoperationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und zugehörige Operationen
Partitionierungsoperationen
(C++11)    

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


 
Definiert in Header <algorithm>
template< class ForwardIt, class T >
bool binary_search( 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 bool binary_search( ForwardIt first, ForwardIt last,
                              const T& value );
(seit C++26)
template< class ForwardIt, class T, class Compare >
bool binary_search( ForwardIt first, ForwardIt last,
                    const T& value, Compare comp );
(2) (bis C++26)
(constexpr seit C++20)
template< class ForwardIt, class T = typename std::iterator_traits
                                         <ForwardIt>::value_type,
          class Compare >
constexpr bool binary_search( ForwardIt first, ForwardIt last,
                              const T& value, Compare comp );
(seit C++26)

Überprüft, ob ein zu value äquivalentes Element im partitionierten Bereich [first, last) vorhanden ist.

1) Die Äquivalenz wird mit operator< überprüft:

Wenn !bool(*iter < value) && !bool(value < *iter) für einen Iterator true in iter [first, last) ist, wird true zurückgegeben. Andernfalls wird false zurückgegeben.

Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:

  • Für jedes Element elem von [first, last) impliziert bool(elem < value) nicht !bool(value < elem).
  • Die Elemente elem von [first, last) sind nicht partitioniert in Bezug auf die Ausdrücke bool(elem < value) und !bool(value < elem).
(bis C++20)

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

(seit C++20)
2) Die Äquivalenz wird mit comp überprüft:
Wenn !bool(comp(*iter, value)) && !bool(comp(value, *iter)) für einen Iterator true in iter [first, last) ist, wird true zurückgegeben. Andernfalls wird false zurückgegeben.
Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:
  • Für jedes Element elem von [first, last) impliziert bool(comp(elem, value)) nicht !bool(comp(value, elem)).
  • Die Elemente elem von [first, last) sind nicht partitioniert in Bezug auf die Ausdrücke bool(comp(elem, value)) und !bool(comp(value, elem)).

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 der folgenden entsprechen:

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

Obwohl die Signatur kein const & haben muss, darf die Funktion die übergebenen Objekte nicht modifizieren und muss in der Lage sein, alle Werte des Typs (möglicherweise const) Type1 und Type2 unabhängig von der Wertkategorie zu akzeptieren (daher ist Type1 & nicht erlaubt, auch nicht , es sei denn, für Type1 ist eine Verschiebung äquivalent zu einer KopieType1(seit C++11)). Die Typen
und Type1 müssen so sein, dass ein Objekt vom Typ Type2 implizit in sowohl T als auch Type1 konvertiert werden kann, und ein Objekt vom Typ Type2 kann dereferenziert und dann implizit in sowohl ForwardIt als auch Type1 konvertiert werden. ​ Type2Typanforderungen

-
muss die Anforderungen von
ForwardItLegacyForwardIterator erfüllen. -
muss die Anforderungen von
CompareBinaryPredicate erfüllen. Es ist nicht erforderlich, Compare zu erfüllen. Rückgabewert

true wenn ein zu value äquivalentes Element gefunden wird, false sonst.

Komplexität

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

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

Wenn ForwardIt jedoch kein LegacyRandomAccessIterator ist, ist die Anzahl der Iteratorinkremente linear in N.

Anmerkungen

Obwohl std::binary_search nur erfordert, dass [first, last) partitioniert ist, wird dieser Algorithmus normalerweise verwendet, wenn [first, last) sortiert ist, damit die binäre Suche für jeden value gültig ist.

std::binary_search überprüft nur, ob ein äquivalentes Element vorhanden ist. Um einen Iterator zu diesem Element zu erhalten (falls vorhanden), sollte std::lower_bound verwendet werden.

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

Mögliche Implementierung

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

binary_search (1)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type>
bool binary_search(ForwardIt first, ForwardIt last, const T& value)
{
    return std::binary_search(first, last, value, std::less{});
}
binary_search (2)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type,
         class Compare>
bool binary_search(ForwardIt first, ForwardIt last, const T& value, Compare comp)
{
    first = std::lower_bound(first, last, value, comp);
    return (!(first == last) and !(comp(value, *first)));
}

Beispiel

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

int main()
{
    const auto haystack = {1, 3, 4, 5, 9};
    
    for (const auto needle : {1, 2, 3})
    {
        std::cout << "Searching for " << needle << '\n';
        if (std::binary_search(haystack.begin(), haystack.end(), needle))
            std::cout << "Found " << needle << '\n';
        else
            std::cout << "Not found!\n";
    }

    using CD = std::complex<double>;
    std::vector<CD> nums{{1, 1}, {2, 3}, {4, 2}, {4, 3}};
    auto cmpz = [](CD x, CD y){ return abs(x) < abs(y); };
    #ifdef __cpp_lib_algorithm_default_value_type
        assert(std::binary_search(nums.cbegin(), nums.cend(), {4, 2}, cmpz));
    #else
        assert(std::binary_search(nums.cbegin(), nums.cend(), CD{4, 2}, cmpz));
    #endif
}

Ausgabe:

Searching for 1
Found 1
Searching for 2
Not found!
Searching for 3
Found 3

Fehlerberichte

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

DR Angewendet auf Verhalten wie veröffentlicht Richtiges Verhalten
LWG 270 C++98 Compare war erforderlich, um Compare zu erfüllen, und T war erforderlich
um LessThanComparable zu sein (strenge schwache Ordnung erforderlich)
nur eine Partitionierung ist erforderlich;
heterogene Vergleiche erlaubt
LWG 787 C++98 höchstens log2(N)+2 Vergleiche waren erlaubt korrigiert auf log2(N)+O(1)

Siehe auch

findet den Bereich von Elementen, die dem angegebenen Wert entsprechen, mittels binärer Suche
(Funktionsschablone & Algorithmusfunktionsobjekt)
findet das erste Element, das nicht kleiner als der angegebene Wert ist, mittels binärer Suche
(Funktionsschablone & Algorithmusfunktionsobjekt)
findet das erste Element, das größer als der angegebene Wert ist, mittels binärer Suche
(Funktionsschablone & Algorithmusfunktionsobjekt)
bestimmt, ob ein Element in einem Bereich vorhanden ist, mittels binärer Suche
(Algorithmusfunktionsobjekt)