std:: equal_range
|
헤더 파일에 정의됨
<algorithm>
|
||
| (1) | ||
|
template
<
class
ForwardIt,
class
T
>
std::
pair
<
ForwardIt, ForwardIt
>
|
(C++20부터 constexpr)
(C++26까지) |
|
|
template
<
class
ForwardIt,
class
T
=
typename
std::
iterator_traits
<
ForwardIt
>
::
value_type
>
|
(C++26부터) | |
| (2) | ||
|
template
<
class
ForwardIt,
class
T,
class
Compare
>
std::
pair
<
ForwardIt, ForwardIt
>
|
(C++20부터 constexpr)
(C++26까지) |
|
|
template
<
class
ForwardIt,
class
T
=
typename
std::
iterator_traits
<
ForwardIt
>
::
value_type
,
|
(C++26부터) | |
분할된 범위
[
first
,
last
)
에서
value
와 동등한 모든 요소를 포함하는 범위를 반환합니다.
|
std:: lower_bound ( first, last, value ) 와 std:: upper_bound ( first, last, value ) 의 결과를 반환합니다. 다음 조건 중 하나라도 만족되면 동작은 정의되지 않습니다:
|
(C++20 이전) |
|
std :: equal_range ( first, last, value, std:: less { } ) 와 동등합니다. |
(C++20 이후) |
-
[first,last)범위의 임의의 요소 elem 에 대해, bool ( comp ( elem, value ) ) 가 ! bool ( comp ( value, elem ) ) 를 함의하지 않는 경우. -
[first,last)범위의 요소들 elem 이 표현식 bool ( comp ( elem, value ) ) 및 ! bool ( comp ( value, elem ) ) 에 대해 분할 되지 않은 경우.
목차 |
매개변수
| first, last | - | 검사할 요소들의 분할된 범위 를 정의하는 반복자 쌍 |
| value | - | 요소들과 비교할 값 |
| comp | - |
첫 번째 인수가 두 번째 인수보다 앞에 정렬된 경우
true
를 반환하는 이항 predicate
predicate 함수의 시그니처는 다음에 해당해야 합니다: bool pred ( const Type1 & a, const Type2 & b ) ;
시그니처에
const
&
가 필요하지는 않지만, 함수는 전달된 객체를 수정해서는 안 되며
값 범주
에 관계없이 (가능한 const)
|
| 타입 요구사항 | ||
-
ForwardIt
는
LegacyForwardIterator
의 요구사항을 충족해야 합니다.
|
||
-
Compare
는
BinaryPredicate
의 요구사항을 충족해야 합니다.
Compare
를 충족할 필요는 없습니다.
|
||
반환값
한 쌍의 반복자를 포함하는 std::pair 객체로,
-
first는 범위[first,last)내에서 value 앞에 정렬되지 않은 첫 번째 요소에 대한 반복자입니다(해당 요소가 없으면 last 를 반환). -
second는 범위[first,last)내에서 value 뒤에 정렬된 첫 번째 요소에 대한 반복자입니다(해당 요소가 없으면 last 를 반환).
복잡도
주어진 N 이 std:: distance ( first, last ) 인 경우:
그러나
ForwardIt
가
LegacyRandomAccessIterator
가 아닌 경우, 반복자 증감 횟수는
N
에 대해 선형적입니다. 특히,
std::set
와
std::multiset
의 반복자는 임의 접근이 불가능하므로, 해당 멤버 함수인
std::set::equal_range
(각각
std::multiset::equal_range
)의 사용이 권장됩니다.
참고 사항
비록
std::equal_range
가
[
first
,
last
)
가 분할(partitioned)되기만을 요구하지만, 이 알고리즘은 일반적으로
[
first
,
last
)
가 정렬된 경우에 사용되므로, 이진 검색(binary search)이 어떤
value
에 대해서도 유효합니다.
std::lower_bound
와
std::upper_bound
의 요구사항에 더해,
std::equal_range
는 또한
operator
<
또는
comp
가 비대칭적이어야 합니다 (즉,
a
<
b
와
b
<
a
가 항상 다른 결과를 가져야 합니다).
따라서 이진 검색의 중간 결과는
std::lower_bound
와
std::upper_bound
에 의해 공유될 수 있습니다. 예를 들어,
std::lower_bound
호출의 결과는
first
인자로
std::upper_bound
호출에서 사용될 수 있습니다.
| 기능 테스트 매크로 | 값 | 표준 | 기능 |
|---|---|---|---|
__cpp_lib_algorithm_default_value_type
|
202403
|
(C++26) | 목록 초기화 for algorithms ( 1,2 ) |
가능한 구현
| 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)); } |
예제
#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'; }
출력:
Compare using S::operator<(): B C D Using heterogeneous comparison: B C D (2,2) (2, 1)
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| LWG 270 | C++98 |
Compare
가
Compare
를 만족해야 했고
T
는
LessThanComparable (엄밀한 약순서 요구)이어야 했음 |
분할만 요구됨;
이종 비교 허용됨 |
| LWG 384 | C++98 |
최대
2log
2
(N)+1
비교 횟수 허용,
구현 불가능했음 [1] |
2log 2 (N)+O(1) 로 수정됨 |
-
↑
단일 요소 범위에
equal_range를 적용하려면 2번의 비교가 필요하지만, 복잡도 요구사항에 따라 최대 1번의 비교만 허용됩니다.
참고 항목
|
주어진 값보다
작지 않은
첫 번째 요소에 대한 반복자를 반환합니다
(함수 템플릿) |
|
|
특정 값보다
큰
첫 번째 요소에 대한 반복자를 반환합니다
(함수 템플릿) |
|
|
부분적으로 정렬된 범위에 요소가 존재하는지 확인합니다
(함수 템플릿) |
|
|
요소들의 범위를 두 그룹으로 나눕니다
(함수 템플릿) |
|
|
두 요소 집합이 동일한지 확인합니다
(함수 템플릿) |
|
|
특정 키와 일치하는 요소들의 범위를 반환합니다
(
std::set<Key,Compare,Allocator>
의 public 멤버 함수)
|
|
|
특정 키와 일치하는 요소들의 범위를 반환합니다
(
std::multiset<Key,Compare,Allocator>
의 public 멤버 함수)
|
|
|
(C++20)
|
특정 키와 일치하는 요소들의 범위를 반환합니다
(알고리즘 함수 객체) |