std:: equal_range
|
Definiert im Header
<algorithm>
|
||
| (1) | ||
|
template
<
class
ForwardIt,
class
T
>
std::
pair
<
ForwardIt, ForwardIt
>
|
(constexpr seit C++20)
(bis C++26) |
|
|
template
<
class
ForwardIt,
class
T
=
typename
std::
iterator_traits
<
ForwardIt
>
::
value_type
>
|
(seit C++26) | |
| (2) | ||
|
template
<
class
ForwardIt,
class
T,
class
Compare
>
std::
pair
<
ForwardIt, ForwardIt
>
|
(constexpr seit C++20)
(bis C++26) |
|
|
template
<
class
ForwardIt,
class
T
=
typename
std::
iterator_traits
<
ForwardIt
>
::
value_type
,
|
(seit C++26) | |
Gibt einen Bereich zurück, der alle Elemente enthält, die äquivalent zu
value
im partitionierten Bereich
[
first
,
last
)
sind.
|
Gibt die Ergebnisse von std:: lower_bound ( first, last, value ) und std:: upper_bound ( first, last, value ) zurück. Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:
|
(bis C++20) |
|
Äquivalent zu std :: equal_range ( first, last, value, std:: less { } ) . |
(seit C++20) |
-
Für irgendein Element
elem
von
[first,last), bool ( comp ( elem, value ) ) impliziert nicht ! bool ( comp ( value, elem ) ) . -
Die Elemente
elem
von
[first,last)sind nicht partitioniert bezüglich der Ausdrücke bool ( comp ( elem, value ) ) und ! bool ( comp ( value, elem ) ) .
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)
|
| 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
Ein std::pair das ein Paar von Iteratoren enthält, wobei
-
firstist ein Iterator zum ersten Element des Bereichs[first,last), das nicht vor value geordnet ist (oder last , falls kein solches Element gefunden wird), und -
secondist ein Iterator zum ersten Element des Bereichs[first,last), das nach value geordnet ist (oder last , falls kein solches Element gefunden wird).
Komplexität
Gegeben N als std:: distance ( first, last ) :
Wenn jedoch
ForwardIt
kein
LegacyRandomAccessIterator
ist, ist die Anzahl der Iteratorinkremente linear in
N
. Insbesondere sind
std::set
- und
std::multiset
-Iteratoren keine Random-Access-Iteratoren, daher sollten deren Memberfunktionen
std::set::equal_range
(bzw.
std::multiset::equal_range
) bevorzugt werden.
Hinweise
Obwohl
std::equal_range
nur erfordert, dass
[
first
,
last
)
partitioniert ist, wird dieser Algorithmus üblicherweise in Fällen verwendet, in denen
[
first
,
last
)
sortiert ist, sodass die binäre Suche für jeden
value
gültig ist.
Zusätzlich zu den Anforderungen von
std::lower_bound
und
std::upper_bound
erfordert
std::equal_range
außerdem, dass
operator
<
oder
comp
asymmetrisch sind (d.h.,
a
<
b
und
b
<
a
immer unterschiedliche Ergebnisse liefern).
Daher können die Zwischenergebnisse der binären Suche von
std::lower_bound
und
std::upper_bound
gemeinsam genutzt werden. Beispielsweise kann das Ergebnis des
std::lower_bound
-Aufrufs als Argument für
first
im
std::upper_bound
-Aufruf verwendet werden.
| Feature-Test Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_algorithm_default_value_type
|
202403
|
(C++26) | Listeninitialisierung für Algorithmen ( 1,2 ) |
Mögliche Implementierung
| equal_range (1) |
|---|
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type> constexpr std::pair<ForwardIt, ForwardIt> equal_range(ForwardIt first, ForwardIt last, const T& value) { return std::equal_range(first, last, value, std::less{}); } |
| equal_range (2) |
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type, class Compare> constexpr std::pair<ForwardIt, ForwardIt> equal_range(ForwardIt first, ForwardIt last, const T& value, Compare comp) { return std::make_pair(std::lower_bound(first, last, value, comp), std::upper_bound(first, last, value, comp)); } |
Beispiel
#include <algorithm> #include <complex> #include <iostream> #include <vector> struct S { int number; char name; // note: name is ignored by this comparison operator bool operator<(const S& s) const { return number < s.number; } }; struct Comp { bool operator()(const S& s, int i) const { return s.number < i; } bool operator()(int i, const S& s) const { return i < s.number; } }; int main() { // note: not ordered, only partitioned w.r.t. S defined below const std::vector<S> vec{{1, 'A'}, {2, 'B'}, {2, 'C'}, {2, 'D'}, {4, 'G'}, {3, 'F'}}; const S value{2, '?'}; std::cout << "Compare using S::operator<(): "; const auto p = std::equal_range(vec.begin(), vec.end(), value); for (auto it = p.first; it != p.second; ++it) std::cout << it->name << ' '; std::cout << '\n'; std::cout << "Using heterogeneous comparison: "; const auto p2 = std::equal_range(vec.begin(), vec.end(), 2, Comp{}); for (auto it = p2.first; it != p2.second; ++it) std::cout << it->name << ' '; 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 p3 = std::equal_range(nums.cbegin(), nums.cend(), {2, 0}, cmpz); #else auto p3 = std::equal_range(nums.cbegin(), nums.cend(), CD{2, 0}, cmpz); #endif for (auto it = p3.first; it != p3.second; ++it) std::cout << *it << ' '; std::cout << '\n'; }
Ausgabe:
Compare using S::operator<(): B C D Using heterogeneous comparison: B C D (2,2) (2, 1)
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
2log
2
(N)+1
Vergleiche
erlaubt, was nicht implementierbar ist [1] |
korrigiert auf 2log 2 (N)+O(1) |
-
↑
Die Anwendung von
equal_rangeauf einen Einzelelement-Bereich erfordert 2 Vergleiche, aber gemäß der Komplexitätsanforderung ist höchstens 1 Vergleich zulässig.
Siehe auch
|
gibt einen Iterator zum ersten Element zurück,
das nicht kleiner
als der gegebene Wert ist
(Funktions-Template) |
|
|
gibt einen Iterator zum ersten Element zurück,
das größer
als ein bestimmter Wert ist
(Funktions-Template) |
|
|
bestimmt, ob ein Element in einem teilweise geordneten Bereich existiert
(Funktions-Template) |
|
|
teilt einen Elementbereich in zwei Gruppen auf
(Funktions-Template) |
|
|
bestimmt, ob zwei Elementmengen identisch sind
(Funktions-Template) |
|
|
gibt den Bereich der Elemente zurück, die einem spezifischen Schlüssel entsprechen
(öffentliche Elementfunktion von
std::set<Key,Compare,Allocator>
)
|
|
|
gibt den Bereich der Elemente zurück, die einem spezifischen Schlüssel entsprechen
(öffentliche Elementfunktion von
std::multiset<Key,Compare,Allocator>
)
|
|
|
(C++20)
|
gibt den Bereich der Elemente zurück, die einem spezifischen Schlüssel entsprechen
(Algorithmus-Funktionsobjekt) |