Namespaces
Variants

std:: equal_range

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
equal_range
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
헤더 파일에 정의됨 <algorithm>
(1)
template < class ForwardIt, class T >

std:: pair < ForwardIt, ForwardIt >

equal_range ( ForwardIt first, ForwardIt last, const T & value ) ;
(C++20부터 constexpr)
(C++26까지)
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 ) ;
(C++26부터)
(2)
template < class ForwardIt, class T, class Compare >

std:: pair < ForwardIt, ForwardIt >
equal_range ( ForwardIt first, ForwardIt last,

const T & value, Compare comp ) ;
(C++20부터 constexpr)
(C++26까지)
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 ) ;
(C++26부터)

분할된 범위 [ first , last ) 에서 value 와 동등한 모든 요소를 포함하는 범위를 반환합니다.

1) 동등성은 operator < 를 사용하여 확인됩니다:

std:: lower_bound ( first, last, value ) std:: upper_bound ( first, last, value ) 의 결과를 반환합니다.

다음 조건 중 하나라도 만족되면 동작은 정의되지 않습니다:

  • [ first , last ) 범위의 임의의 요소 elem 에 대해 bool ( elem < value ) ! bool ( value < elem ) 를 함축하지 않는 경우
  • [ first , last ) 범위의 요소들 elem bool ( elem < value ) ! bool ( value < elem ) 표현식에 대해 분할 되지 않은 경우
(C++20 이전)

std :: equal_range ( first, last, value, std:: less { } ) 와 동등합니다.

(C++20 이후)
2) 동등성은 comp 를 사용하여 확인됩니다:
std:: lower_bound ( first, last, value, comp ) std:: upper_bound ( first, last, value, comp ) 의 결과를 반환합니다.
다음 조건 중 하나라도 만족되면 동작은 정의되지 않음:
  • [ 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) Type1 Type2 타입의 모든 값을 수용할 수 있어야 합니다 (따라서 Type1 & 는 허용되지 않으며 , Type1 Type1 에 대해 이동이 복사와 동등하지 않는 한 허용되지 않습니다 (C++11부터) ).
타입 Type1 Type2 T 타입의 객체가 Type1 Type2 양쪽으로 암시적으로 변환 가능해야 하며, ForwardIt 타입의 객체를 역참조한 후 Type1 Type2 양쪽으로 암시적으로 변환 가능해야 합니다. ​

타입 요구사항
-
ForwardIt LegacyForwardIterator 의 요구사항을 충족해야 합니다.
-
Compare BinaryPredicate 의 요구사항을 충족해야 합니다. Compare 를 충족할 필요는 없습니다.

반환값

한 쌍의 반복자를 포함하는 std::pair 객체로,

  • first 는 범위 [ first , last ) 내에서 value 앞에 정렬되지 않은 첫 번째 요소에 대한 반복자입니다(해당 요소가 없으면 last 를 반환).
  • second 는 범위 [ first , last ) 내에서 value 뒤에 정렬된 첫 번째 요소에 대한 반복자입니다(해당 요소가 없으면 last 를 반환).

복잡도

주어진 N std:: distance ( first, last ) 인 경우:

1) 최대 2log 2 (N)+O(1) 번의 비교를 value 와 수행하며, 사용하는 비교 연산은 operator < (C++20 이전) std:: less { } (C++20 이후) 입니다.
2) 최대 2log 2 (N)+O(1) 번의 비교자 comp 적용.

그러나 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) 로 수정됨
  1. 단일 요소 범위에 equal_range 를 적용하려면 2번의 비교가 필요하지만, 복잡도 요구사항에 따라 최대 1번의 비교만 허용됩니다.

참고 항목

주어진 값보다 작지 않은 첫 번째 요소에 대한 반복자를 반환합니다
(함수 템플릿)
특정 값보다 첫 번째 요소에 대한 반복자를 반환합니다
(함수 템플릿)
부분적으로 정렬된 범위에 요소가 존재하는지 확인합니다
(함수 템플릿)
요소들의 범위를 두 그룹으로 나눕니다
(함수 템플릿)
두 요소 집합이 동일한지 확인합니다
(함수 템플릿)
특정 키와 일치하는 요소들의 범위를 반환합니다
( std::set<Key,Compare,Allocator> 의 public 멤버 함수)
특정 키와 일치하는 요소들의 범위를 반환합니다
( std::multiset<Key,Compare,Allocator> 의 public 멤버 함수)
특정 키와 일치하는 요소들의 범위를 반환합니다
(알고리즘 함수 객체)