Namespaces
Variants

std::ranges::binary_search

Von de.cppreference.net
 
 
Algorithmenbibliothek
Eingeschränkte Algorithmen und Algorithmen über Bereiche (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
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)
Mischoperationen (auf sortierten Bereichen)
Heap-Operationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikografische Vergleichsoperationen
Permutationsoperationen


 
Eingeschränkte Algorithmen
Alle Namen in diesem Menü gehören zum Namensraum std::ranges
Nicht modifizierende Sequenzoperationen
Modifizierende Sequenzoperationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen (auf sortierten Bereichen)
       
       
Mengenoperationen (auf sortierten Bereichen)
Heap-Operationen
Minimum/Maximum-Operationen
       
       
Permutationsoperationen
Faltungsoperationen
Numerische Operationen
(C++23)            
Operationen auf nicht initialisiertem Speicher
Rückgabetypen
 
Definiert in Header <algorithm>
Aufrufsignatur
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 bool binary_search( I first, S last, const T& value,
                              Comp comp = {}, Proj proj = {} );
(1) (seit C++20)
(bis 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 bool binary_search( I first, S last, const T& value,
                              Comp comp = {}, Proj proj = {} );
(seit C++26)
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 bool binary_search( R&& r, const T& value,
                              Comp comp = {}, Proj proj = {} );
(2) (seit C++20)
(bis 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 bool binary_search( R&& r, const T& value,
                              Comp comp = {}, Proj proj = {} );
(seit C++26)
1) Prüft, ob ein projiziertes Element, das value entspricht, innerhalb des Bereichs [first, last) vorkommt.
2) Wie (1), verwendet jedoch r als Quellbereich, als ob ranges::begin(r) als first und ranges::end(r) als last verwendet würde.

Damit ranges::binary_search erfolgreich ist, muss der Bereich [first, last) bezüglich value zumindest teilweise geordnet sein, d. h. er muss alle folgenden Anforderungen erfüllen:

  • partitioniert bezüglich std::invoke(comp, std::invoke(proj, element), value) (d. h., alle projizierten Elemente, für die der Ausdruck true ist, stehen vor allen Elementen, für die der Ausdruck false ist).
  • partitioniert bezüglich !std::invoke(comp, value, std::invoke(proj, element)).
  • für alle Elemente gilt: Wenn std::invoke(comp, std::invoke(proj, element), value) true ist, dann ist !std::invoke(comp, value, std::invoke(proj, element)) ebenfalls true.

Ein vollständig sortierter Bereich erfüllt diese Kriterien.

Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithmus-Funktionsobjekte (informell als Niebloids bekannt), das heißt:

Parameter

first, last - das Iterator-Sentinel-Paar, das den Bereich der zu untersuchenden Elemente definiert
r - der Bereich der zu untersuchenden Elemente
value - Wert, mit dem die Elemente verglichen werden sollen
comp - Vergleichsfunktion, die auf die projizierten Elemente angewendet wird
proj - Projektion, die auf die Elemente angewendet wird

Rückgabewert

true wenn ein Element gleich value gefunden wird, false andernfalls.

Komplexität

Die Anzahl der durchgeführten Vergleiche und Projektionen ist logarithmisch zur Entfernung zwischen first und last (höchstens log2(last - first) + O(1) Vergleiche und Projektionen). Für Iterator-Sentinel-Paare, die kein std::random_access_iterator modellieren, ist die Anzahl der Iteratorinkremente jedoch linear.

Hinweise

std::ranges::binary_search gibt keinen Iterator zum gefundenen Element zurück, wenn ein Element gefunden wird, dessen Projektion gleich value ist. Wenn ein Iterator gewünscht wird, sollte std::ranges::lower_bound verwendet werden.

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

Mögliche Implementierung

struct binary_search_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 bool operator()(I first, S last, const T& value,
                              Comp comp = {}, Proj proj = {}) const
    {
        auto x = ranges::lower_bound(first, last, value, comp, proj);
        return (!(x == last) && !(std::invoke(comp, value, std::invoke(proj, *x))));
    }
    
    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 bool operator()(R&& r, const T& value, Comp comp = {}, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), value,
                       std::move(comp), std::move(proj));
    }
};

inline constexpr binary_search_fn binary_search;

Beispiel

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

int main()
{
    constexpr static auto haystack = {1, 3, 4, 5, 9};
    static_assert(std::ranges::is_sorted(haystack));
    
    for (const int needle : std::views::iota(1)
                          | std::views::take(3))
    {
        std::cout << "Searching for " << needle << ": ";
        std::ranges::binary_search(haystack, needle)
            ? std::cout << "found " << needle << '\n'
            : std::cout << "no dice!\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::ranges::binary_search(nums, {4, 2}, cmpz));
    #else
        assert(std::ranges::binary_search(nums, CD{4, 2}, cmpz));
    #endif
}

Ausgabe:

Searching for 1: found 1
Searching for 2: no dice!
Searching for 3: found 3

Siehe auch

findet den Bereich von Elementen, die dem gegebenen Wert entsprechen, mittels binärer Suche
(Algorithmus-Funktionsobjekt)
findet das erste Element, das nicht kleiner als der gegebene Wert ist, mittels binärer Suche
(Algorithmus-Funktionsobjekt)
findet das erste Element, das größer als der gegebene Wert ist, mittels binärer Suche
(Algorithmus-Funktionsobjekt)
prüft, ob der Bereich das gegebene Element oder den Teilbereich enthält
(Algorithmus-Funktionsobjekt)
bestimmt, ob ein Element in einem Bereich mittels binärer Suche existiert
(Funktionsschablone)