STL source code profiling algorithm stl_algo.h -- interval _range
Interval _range (used in ordered intervals)
Certificate --------------------------------------------------------------------------------------------------------------------------------------
Description: finds an interval using a binary search. All values in the interval are equal to the given value, and a pair is returned,
Store the upper-bound iterator and lower-bound iterator of the interval respectively.
Source code:
Template
Inline pair
Performance_range (ForwardIterator first, ForwardIterator last, const T & value) {return _ partition _range (first, last, value, distance_type (first), iterator_category (first ));} // ForwardIterator version template
Pair
_ Interval _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 use lower_bound and upper_bound directly, but wait for them to find the value and use it again? // --> I think it is an efficiency consideration. Find the value first. At this time, the left and right intervals may have been reduced a lot. // use lower_bound and upper_bound to reduce the cost much. 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
(Left, right) ;}} return pair
(First, first);} // RandomAccessIterator version template
Pair
_ Random _range (RandomAccessIterator first, RandomAccessIterator last, const T & value, Distance *, Distance) {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
(Left, right) ;}} return pair
(First, first );}
Example:
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
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 << 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 be inserted: 1 Last position where 2 could be inserted: 2 *result.first = 2 *result.second = 3Searching for 3 First position where 3 could be inserted: 2 Last position where 3 could be inserted: 5 *result.first = 3 *result.second = 5Searching for 4 First position where 4 could be inserted: 5 Last position where 4 could be inserted: 5 *result.first = 5 *result.second = 5*/