This article is Senlie original, reprint please retain this address:Http://blog.csdn.net/zhengsenlie
Equal_range (applied to ordered interval)
--------------------------------------------------------------------------------------------------------------- -----------------------
Descriptive narration: Using binary search to find an interval, all values in the interval are equal to the given value, and a pair is returned.
Upper bound iterators and nether iterators for each storage interval
Source:
Template <class ForwardIterator, class T>inline Pair<forwarditerator, Forwarditerator>equal_range ( ForwardIterator first, ForwardIterator last, const t& value) {return __equal_range (first, last, value, Distance_type (first), Iterator_category (first));} ForwardIterator version number template <class ForwardIterator, class T, class Distance>pair<forwarditerator, Forwarditerator>__equal_range (ForwardIterator First, ForwardIterator last, const t& value, distance*, Forward_iterator_tag) {Distance len = 0; Distance (first, last, Len); Distance half; ForwardIterator middle, left, right; while (Len > 0) {//strange? Why not just use Lower_bound, upper_bound, but wait to find the value to use again? And I think it's about efficiency.Find value first, then the left and right two intervals may have shrunk a lot. Re-using Lower_bound and upper_bound cost a lot less half = Len >> 1; middle = first; Advance (middle, half); if (*middle < value) {first = middle; ++first; len = len-half-1; } else if (value < *middle) len = half; else {left = Lower_bound (first, middle, value); Advance (first, Len); right = Upper_bound (++middle, first, value); Return Pair<forwarditerator, forwarditerator> (left, right); }} return Pair<forwarditerator, Forwarditerator> (first, first);} Randomaccessiterator version number template <class Randomaccessiterator, class T, class distance>pair< Randomaccessiterator, Randomaccessiterator>__equal_range (randomaccessiterator First, RandomAccessIterator last, Const t& value, distance*, Random_access_iterator_tag) {Distance len = Last-first; Distance half; Randomaccessiterator Middle, left, right; while (Len > 0) {half = Len >> 1; Middle = First + half; if (*middle < value) {first = middle + 1; len = len-half-1; } else if (value < *middle) len = half; else {left = Lower_bound (first, middle, value); right = Upper_bound (++middle, first + len, value); Return Pair<randomaccessiterator, randomaccessiterator> (left, right); }} return Pair<randomaccessiterator, Randomaccessiterator> (first, first);}
Demo Sample:
int main () { int a[] = {1, 2, 3, 3, 3, 5, 8}; const int N = sizeof (A)/sizeof (int); for (int i = 2; I <= 4; ++i) { pair<int*, int*> result = Equal_range (A, a + N, i); cout << Endl; cout << "Searching for" << i << Endl; cout << "first position where" << I << "could be inserted:" << result.first-a <&L T Endl; cout << "Last position where" << I << "could be inserted:" << result.second-a < < Endl; if (Result.first < A + N) cout << " *result.first =" << *result.first << Endl; if (Result.second < A + N) cout << " *result.second =" << *result.second << Endl; }}
/* The output is:searching for 2 first position where 2 could is inserted:1 last position where 2 could is in Serted:2 *result.first = 2 *result.second = 3Searching for 3 first position where 3 could is inserted:2 Last position where 3 could is inserted:5 *result.first = 3 *result.second = 5Searching for 4 first position Where 4 could is inserted:5 last position where 4 could be inserted:5 *result.first = 5 *result.second = 5*/
STL Source Code Anatomy algorithm Stl_algo.h--Equal_range