Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      std::equal_range

      From cppreference.com
      <cpp‎ |algorithm
       
       
      Algorithm library
      Constrained algorithms and algorithms on ranges(C++20)
      Constrained algorithms, e.g.ranges::copy,ranges::sort, ...
      Execution policies(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
      (C++11)
      (C++17)
      Lexicographical comparison operations
      Permutation operations
      C library
      Numeric operations
      Operations on uninitialized memory
       
      Defined in header<algorithm>
      (1)
      template<class ForwardIt,class T>

      std::pair<ForwardIt, ForwardIt>

          equal_range( ForwardIt first, ForwardIt last,const T& value);
      (constexpr since C++20)
      (until C++26)
      template<class ForwardIt,class T=typenamestd::iterator_traits

                                               <ForwardIt>::value_type>
      constexprstd::pair<ForwardIt, ForwardIt>

          equal_range( ForwardIt first, ForwardIt last,const T& value);
      (since 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);
      (constexpr since C++20)
      (until C++26)
      template<class ForwardIt,class T=typenamestd::iterator_traits

                                               <ForwardIt>::value_type,
               class Compare>
      constexprstd::pair<ForwardIt, ForwardIt>
          equal_range( ForwardIt first, ForwardIt last,

                       const T& value, Compare comp);
      (since C++26)

      Returns a range containing all elements equivalent tovalue in the partitioned range[firstlast).

      1) The equivalence is checked usingoperator<:

      Returns the results ofstd::lower_bound(first, last, value) andstd::upper_bound(first, last, value).

      If any of the following conditions is satisfied, the behavior is undefined:

      • For any elementelem of[firstlast),bool(elem< value) does not imply!bool(value< elem).
      • The elementselem of[firstlast) are notpartitioned with respect to expressionsbool(elem< value) and!bool(value< elem).
      (until C++20)

      Equivalent tostd::equal_range(first, last, value,std::less{}).

      (since C++20)
      2) The equivalence is checked usingcomp:
      Returns the results ofstd::lower_bound(first, last, value, comp) andstd::upper_bound(first, last, value, comp).
      If any of the following conditions is satisfied, the behavior is undefined:
      • For any elementelem of[firstlast),bool(comp(elem, value)) does not imply!bool(comp(value, elem)).
      • The elementselem of[firstlast) are notpartitioned with respect to expressionsbool(comp(elem, value)) and!bool(comp(value, elem)).

      Contents

      [edit]Parameters

      first, last - the pair of iterators defining the partitionedrange of elements to examine
      value - value to compare the elements to
      comp - binary predicate which returns ​true if the first argument is ordered before the second.

      The signature of the predicate function should be equivalent to the following:

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

      While the signature does not need to haveconst&, the function must not modify the objects passed to it and must be able to accept all values of type (possibly const)Type1 andType2 regardless ofvalue category (thus,Type1& is not allowed, nor isType1 unless forType1 a move is equivalent to a copy(since C++11)).
      The typesType1 andType2 must be such that an object of typeT can be implicitly converted to bothType1 andType2, and an object of typeForwardIt can be dereferenced and then implicitly converted to bothType1 andType2.​

      Type requirements
      -
      ForwardIt must meet the requirements ofLegacyForwardIterator.
      -
      Compare must meet the requirements ofBinaryPredicate. It is not required to satisfyCompare.

      [edit]Return value

      Astd::pair containing a pair of iterators, where

      • first is an iterator to the first element of the range[firstlast) not ordered beforevalue (orlast if no such element is found), and
      • second is an iterator to the first element of the range[firstlast) ordered aftervalue (orlast if no such element is found).

      [edit]Complexity

      Given\(\scriptsize N\)N asstd::distance(first, last):

      1) At most\(\scriptsize 2\log_{2}(N)+O(1)\)2log2(N)+O(1) comparisons withvalue usingoperator<(until C++20)std::less{}(since C++20).
      2) At most\(\scriptsize 2\log_{2}(N)+O(1)\)2log2(N)+O(1) applications of the comparatorcomp.

      However, ifForwardIt is not aLegacyRandomAccessIterator, the number of iterator increments is linear in\(\scriptsize N\)N. Notably,std::set andstd::multiset iterators are not random access, and so their member functionsstd::set::equal_range (resp.std::multiset::equal_range) should be preferred.

      [edit]Notes

      Althoughstd::equal_range only requires[firstlast) to be partitioned, this algorithm is usually used in the case where[firstlast) is sorted, so that the binary search is valid for anyvalue.

      On top of the requirements ofstd::lower_bound andstd::upper_bound,std::equal_range also requiresoperator< orcomp to be asymmetric (i.e.,a< b andb< a always have different results).

      Therefore, the intermediate results of binary search can be shared bystd::lower_bound andstd::upper_bound. For example, the result of thestd::lower_bound call can be used as the argument offirst in thestd::upper_bound call.

      Feature-test macroValueStdFeature
      __cpp_lib_algorithm_default_value_type202403(C++26)List-initialization for algorithms(1,2)

      [edit]Possible implementation

      equal_range (1)
      template<class ForwardIt,class T=typenamestd::iterator_traits<ForwardIt>::value_type>constexprstd::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=typenamestd::iterator_traits<ForwardIt>::value_type,class Compare>constexprstd::pair<ForwardIt, ForwardIt>    equal_range(ForwardIt first, ForwardIt last,const T& value, Compare comp){returnstd::make_pair(std::lower_bound(first, last, value, comp),std::upper_bound(first, last, value, comp));}

      [edit]Example

      Run this code
      #include <algorithm>#include <complex>#include <iostream>#include <vector> struct S{int number;char name;// note: name is ignored by this comparison operatorbool 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 belowconststd::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<(): ";constauto 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: ";constauto 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_typeauto p3= std::equal_range(nums.cbegin(), nums.cend(),{2,0}, cmpz);#elseauto 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';}

      Output:

      Compare using S::operator<(): B C D Using heterogeneous comparison: B C D(2,2) (2, 1)

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      LWG 270C++98Compare was required to satisfyCompare andT was required
      to beLessThanComparable (strict weak ordering required)
      only a partitioning is required;
      heterogeneous comparisons permitted
      LWG 384C++98at most\(\scriptsize 2\log_{2}(N)+1\)2log2(N)+1 comparisons
      were allowed, which is not implementable[1]
      corrected to\(\scriptsize 2\log_{2}(N)+O(1)\)2log2(N)+O(1)
      1. Applyingequal_range to a single-element range requires 2 comparisons, but at most 1 comparison is allowed by the complexity requirement.

      [edit]See also

      returns an iterator to the first elementnot less than the given value
      (function template)[edit]
      returns an iterator to the first elementgreater than a certain value
      (function template)[edit]
      determines if an element exists in a partially-ordered range
      (function template)[edit]
      divides a range of elements into two groups
      (function template)[edit]
      determines if two sets of elements are the same
      (function template)[edit]
      returns range of elements matching a specific key
      (public member function ofstd::set<Key,Compare,Allocator>)[edit]
      returns range of elements matching a specific key
      (public member function ofstd::multiset<Key,Compare,Allocator>)[edit]
      returns range of elements matching a specific key
      (algorithm function object)[edit]
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/algorithm/equal_range&oldid=180598"

      [8]ページ先頭

      ©2009-2025 Movatter.jp