標籤:style blog http color os io
本文為senlie原創,轉載請保留此地址:http://blog.csdn.net/zhengsenlie
equal_range(應用於有序區間)
--------------------------------------------------------------------------------------------------------------------------------------
描述:利用二分尋找找到一個區間,區間裡的所有值都等於給定值,返回的是一個pair,
分別儲存區間的上界迭代器和下界迭代器
源碼:
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 版本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) { // 奇怪? 為什麼不直接用 lower_bound 、 upper_bound , 而是等找到值再用?// --> 我覺得是效率方面的考慮。先找 value ,這時左右兩個區間可能已經縮小了許多,// 再利用 lower_bound 和 upper_bound 代價小很多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 版本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);}
樣本:
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 << 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*/