STL函数对象

最后更新于:2022-04-01 15:51:41

### 前言   在STL中,函数对象也是比较重要的,有时候可以限定STL算法的行为,例如在前面介绍的《[STL](http://blog.csdn.net/chenhanzhun/article/details/39698523)[算法剖析](http://blog.csdn.net/chenhanzhun/article/details/39698523)》中,每个算法基本上都提供了两个操作版本,其中就有一个版本允许用户指定函数对象,这样可以根据用户的需要对算法进行操作。函数对象是一种具有函数特质的对象,所以可以作为算法的参数。本文介绍的函数对象比较简单,是基于一元或者二元操作结构的算术类函数对象、关系运算类函数对象、逻辑运算类函数对象。在定义函数对象时,为了使其具有函数行为,则必须重载operator()操作符。本文源码出自SGI STL中的<stl_function.h>文件。 ### 函数对象源码剖析 ~~~ _STL_BEGIN_NAMESPACE //一元操作结构定义 template <class _Arg, class _Result> struct unary_function { typedef _Arg argument_type;//参数类型 typedef _Result result_type;//返回结果类型 }; //二元操作结构定义 template <class _Arg1, class _Arg2, class _Result> struct binary_function { typedef _Arg1 first_argument_type;//参数一类型 typedef _Arg2 second_argument_type;//参数二类型 typedef _Result result_type;//返回结果类型 }; //以下是二元操作算术函数对象,继承二元操作binary_function的结构 /* 加法操作plus<T>,减法操作minus<T>,乘法操作multiplies<T>,除法操作divides<T>, 取模运算modulus<T>, */ template <class _Tp> struct plus : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; } }; template <class _Tp> struct minus : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; } }; template <class _Tp> struct multiplies : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } }; template <class _Tp> struct divides : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; } }; template <class _Tp> struct modulus : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; } }; //一元操作,继承一元操作unary_function结构 //负值操作negate<T> template <class _Tp> struct negate : public unary_function<_Tp,_Tp> { _Tp operator()(const _Tp& __x) const { return -__x; } }; // identity_element (not part of the C++ standard). //证同元素: //以下只提供的两种证同元素 //加法:任何元素加上0结果都为自身 //乘法:任何元素乘以1结果都为自身 template <class _Tp> inline _Tp identity_element(plus<_Tp>) { return _Tp(0); } template <class _Tp> inline _Tp identity_element(multiplies<_Tp>) { return _Tp(1); } //以下是二元操作关系函数对象,继承二元操作的结构 /* 返回值的类型是bool型别 equal_to,not_equal_to,greater,less,greater_equal,less_equal, */ template <class _Tp> struct equal_to : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } }; template <class _Tp> struct not_equal_to : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; } }; template <class _Tp> struct greater : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } }; template <class _Tp> struct less : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } }; template <class _Tp> struct greater_equal : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; } }; template <class _Tp> struct less_equal : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; } }; //以下是二元操作逻辑函数对象,继承二元操作的结构 /* 其中logical_not为一元操作函数 logical_and,logical_or,logical_not */ template <class _Tp> struct logical_and : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; } }; template <class _Tp> struct logical_or : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; } }; template <class _Tp> struct logical_not : public unary_function<_Tp,bool> { bool operator()(const _Tp& __x) const { return !__x; } }; // identity is an extensions: it is not part of the standard. //证同函数 //任何数值通过此函数后,不会有任何修改。所以返回值类型为const引用 template <class _Tp> struct _Identity : public unary_function<_Tp,_Tp> { const _Tp& operator()(const _Tp& __x) const { return __x; } }; template <class _Tp> struct identity : public _Identity<_Tp> {}; // select1st and select2nd are extensions: they are not part of the standard. //选择函数 //版本一:选择pair元素的第一个参数,忽略第二个参数 template <class _Pair> struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { const typename _Pair::first_type& operator()(const _Pair& __x) const { return __x.first; } }; //版本二:选择pair元素的第二个参数,忽略第一个参数 template <class _Pair> struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type> { const typename _Pair::second_type& operator()(const _Pair& __x) const { return __x.second; } }; template <class _Pair> struct select1st : public _Select1st<_Pair> {}; template <class _Pair> struct select2nd : public _Select2nd<_Pair> {}; // project1st and project2nd are extensions: they are not part of the standard //投射函数 //版本一:投射出第一个参数,忽略第二个参数 template <class _Arg1, class _Arg2> struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> { _Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; } }; //版本二:投射出第二个参数,忽略第一个参数 template <class _Arg1, class _Arg2> struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; } }; template <class _Arg1, class _Arg2> struct project1st : public _Project1st<_Arg1, _Arg2> {}; template <class _Arg1, class _Arg2> struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; ~~~ 参考资料: 《STL源码剖析》侯捷
';

STL算法之permutation排列组合

最后更新于:2022-04-01 15:51:39

### 前言   由于在前文的《[STL算法剖析](http://blog.csdn.net/chenhanzhun/article/details/39698523)》中,源码剖析非常多,不方便学习,也不方便以后复习,这里把这些算法进行归类,对他们单独的源码剖析进行讲解。本文讲解的是STL算法中的permutation排列组合算法,根据输入序列,排列出下一个排列组合或前一个排列组合。 ### permutation排列组合源码剖析 ~~~ // next_permutation and prev_permutation, with and without an explicitly // supplied comparison function. //next_permutation获取[first,last)区间所标示序列的下一个排列组合,若果没有下一个排序组合,则返回false;否则返回true; /* 函数功能:Rearranges the elements in the range [first,last) into the next lexicographically greater permutation. 函数原型: default (1) :版本一采用less-than操作符 template <class BidirectionalIterator> bool next_permutation (BidirectionalIterator first, BidirectionalIterator last); custom (2) :版本二采用仿函数comp决定 template <class BidirectionalIterator, class Compare> bool next_permutation (BidirectionalIterator first, BidirectionalIterator last, Compare comp); */ //版本一 template <class _BidirectionalIter> bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type, _LessThanComparable); if (__first == __last) return false;//若为空,则返回false _BidirectionalIter __i = __first; ++__i; if (__i == __last)//区间只有一个元素 return false; //若区间元素个数不小于两个 __i = __last;//i指向尾端 --__i;//不断后移 for(;;) { //下面两行是让ii和i成为相邻的元素 //其中i为第一个元素,ii为第二个元素 _BidirectionalIter __ii = __i;// --__i; //以下在相邻元素判断 if (*__i < *__ii) {//若前一个元素小于后一个元素, //则再从最尾端开始往前检查,找出第一个大于*i的元素,令该元素为*j,将*i和*j交换 //再将ii之后的所有元素颠倒排序 _BidirectionalIter __j = __last;//令j指向最尾端 while (!(*__i < *--__j))//由尾端往前检查,直到遇到比*i大的元素 {} iter_swap(__i, __j);//交换迭代器i和迭代器j所指的元素 reverse(__ii, __last);//将ii之后的元素全部逆向重排 return true; } if (__i == __first) {//进行到最前面 reverse(__first, __last);//整个区间全部逆向重排 return false; } } } //版本二 template <class _BidirectionalIter, class _Compare> bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last, _Compare __comp) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_BidirectionalIter>::value_type, typename iterator_traits<_BidirectionalIter>::value_type); if (__first == __last) return false; _BidirectionalIter __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; for(;;) { _BidirectionalIter __ii = __i; --__i; if (__comp(*__i, *__ii)) { _BidirectionalIter __j = __last; while (!__comp(*__i, *--__j)) {} iter_swap(__i, __j); reverse(__ii, __last); return true; } if (__i == __first) { reverse(__first, __last); return false; } } } //next_permutation函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::next_permutation, std::sort int main () { int myints[] = {1,2,3,4}; std::sort (myints,myints+4); std::cout << "The 3! possible permutations with 3 elements:\n"; do { std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] <<' ' << myints[3]<< '\n'; } while ( std::next_permutation(myints,myints+4) ); //std::next_permutation(myints,myints+4); std::cout << "After loop: " << myints[0] << ' ' << myints[1] << ' ' << myints[2] << ' ' << myints[3]<<'\n'; return 0; } Output: The 3! possible permutations with 3 elements: 1 2 3 4 1 2 4 3 1 3 2 4 1 3 4 2 1 4 2 3 1 4 3 2 2 1 3 4 2 1 4 3 2 3 1 4 2 3 4 1 2 4 1 3 2 4 3 1 3 1 2 4 3 1 4 2 3 2 1 4 3 2 4 1 3 4 1 2 3 4 2 1 4 1 2 3 4 1 3 2 4 2 1 3 4 2 3 1 4 3 1 2 4 3 2 1 After loop: 1 2 3 4 */ //prev_permutation获取[first,last)区间所标示序列的上一个排列组合,若果没有上一个排序组合,则返回false;否则返回true; /* 函数功能:Rearranges the elements in the range [first,last) into the previous lexicographically-ordered permutation. 函数原型: default (1) :版本一采用less-than操作符 template <class BidirectionalIterator> bool prev_permutation (BidirectionalIterator first, BidirectionalIterator last ); custom (2) :版本二采用仿函数comp template <class BidirectionalIterator, class Compare> bool prev_permutation (BidirectionalIterator first, BidirectionalIterator last, Compare comp); */ //版本一 template <class _BidirectionalIter> bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type, _LessThanComparable); if (__first == __last) return false;//若区间为空,返回false _BidirectionalIter __i = __first; ++__i; if (__i == __last)//区间只有一个元素 return false;//返回false //若区间元素个数不小于两个 __i = __last; --__i; for(;;) { //下面两行是让ii和i成为相邻的元素 //其中i为第一个元素,ii为第二个元素 _BidirectionalIter __ii = __i; --__i; //以下在相邻元素判断 if (*__ii < *__i) {//若前一个元素大于后一个元素, //则再从最尾端开始往前检查,找出第一个小于*i的元素,令该元素为*j,将*i和*j交换 //再将ii之后的所有元素颠倒排序 _BidirectionalIter __j = __last;//令j指向最尾端 while (!(*--__j < *__i))//由尾端往前检查,直到遇到比*i小的元素 {} iter_swap(__i, __j); //交换迭代器i和迭代器j所指的元素 reverse(__ii, __last);//将ii之后的元素全部逆向重排 return true; } if (__i == __first) {//进行到最前面 reverse(__first, __last);//把区间所有元素逆向重排 return false; } } } //版本二 template <class _BidirectionalIter, class _Compare> bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last, _Compare __comp) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_BidirectionalIter>::value_type, typename iterator_traits<_BidirectionalIter>::value_type); if (__first == __last) return false; _BidirectionalIter __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; for(;;) { _BidirectionalIter __ii = __i; --__i; if (__comp(*__ii, *__i)) { _BidirectionalIter __j = __last; while (!__comp(*--__j, *__i)) {} iter_swap(__i, __j); reverse(__ii, __last); return true; } if (__i == __first) { reverse(__first, __last); return false; } } } //prev_permutation函数举例 /* #include <iostream> // std::cout #include <algorithm> // std::next_permutation, std::sort, std::reverse int main () { int myints[] = {1,2,3}; std::sort (myints,myints+3); std::reverse (myints,myints+3); std::cout << "The 3! possible permutations with 3 elements:\n"; do { std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n'; } while ( std::prev_permutation(myints,myints+3) ); std::cout << "After loop: " << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n'; return 0; } Output: The 3! possible permutations with 3 elements: 3 2 1 3 1 2 2 3 1 2 1 3 1 3 2 1 2 3 After loop: 3 2 1 */ ~~~ 参考资料: 《STL源码剖析》侯捷
';

STL算法之remove删除算法

最后更新于:2022-04-01 15:51:36

### 前言   由于在前文的《[STL算法剖析](http://blog.csdn.net/chenhanzhun/article/details/39698523)》中,源码剖析非常多,不方便学习,也不方便以后复习,这里把这些算法进行归类,对他们单独的源码剖析进行讲解。本文介绍的STL算法中的remove删除算法,源码中介绍了函数remove、remove_copy、remove_if、remove_copy_if、unique、unique_copy。并对这些函数的源码进行详细的剖析,并适当给出使用例子,具体详见下面源码剖析。 ### remove移除算法源码剖析 ~~~ // remove, remove_if, remove_copy, remove_copy_if //移除[first,last)区间内所有与value值相等的元素,并不是真正的从容器中删除这些元素(原容器的内容不会改变) //而是将结果复制到一个以result为起始位置的容器中。新容器可以与原容器重叠 template <class _InputIter, class _OutputIter, class _Tp> _OutputIter remove_copy(_InputIter __first, _InputIter __last, _OutputIter __result, const _Tp& __value) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_InputIter>::value_type, _Tp); for ( ; __first != __last; ++__first)//遍历容器 if (!(*__first == __value)) {//如果不相等 *__result = *__first;//赋值给新容器 ++__result;//新容器前进一个位置 } return __result; } //移除[first,last)区间内被仿函数pred判断为true的元素,并不是真正的从容器中删除这些元素(原容器的内容不会改变) //而是将结果复制到一个以result为起始位置的容器中。新容器可以与原容器重叠 template <class _InputIter, class _OutputIter, class _Predicate> _OutputIter remove_copy_if(_InputIter __first, _InputIter __last, _OutputIter __result, _Predicate __pred) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_InputIter>::value_type); for ( ; __first != __last; ++__first)//遍历容器 if (!__pred(*__first)) {//若pred判断为false *__result = *__first;//赋值给新容器 ++__result;//新容器前进一个位置 } return __result; } //移除[first,last)区间内所有与value值相等的元素,该操作不会改变容器大小,只是容器中元素值改变 //即移除之后,重新整理容器的内容 template <class _ForwardIter, class _Tp> _ForwardIter remove(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_ForwardIter>::value_type, _Tp); __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __first = find(__first, __last, __value);//利用顺序查找找出第一个与value相等的元素 _ForwardIter __i = __first; //下面调用remove_copy return __first == __last ? __first : remove_copy(++__i, __last, __first, __value); } //移除[first,last)区间内所有被pred判断为true的元素,该操作不会改变容器大小,只是容器中元素值改变 //即移除之后,重新整理容器的内容 template <class _ForwardIter, class _Predicate> _ForwardIter remove_if(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_ForwardIter>::value_type); __first = find_if(__first, __last, __pred);//利用顺序查找找出第一个与value相等的元素 _ForwardIter __i = __first; //下面调用remove_copy_if return __first == __last ? __first : remove_copy_if(++__i, __last, __first, __pred); } //上面四个移除函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::remove bool IsOdd (int i) { return ((i%2)==1); } int main () { int myints[] = {10,20,31,30,20,11,10,20}; // 10 20 31 30 20 11 10 20 std::vector<int> myvector (8); std::remove_copy (myints,myints+8,myvector.begin(),20); // 10 31 30 11 10 0 0 0 std::cout << "myvector contains:"; for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; // bounds of range: int* pbegin = myints; // ^ int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^ pend = std::remove (pbegin, pend, 20); // 10 31 30 11 10 ? ? ? // ^ ^ std::cout << "range contains:"; for (int* p=pbegin; p!=pend; ++p) std::cout << ' ' << *p; std::cout << '\n'; std::vector<int> myvector2 (7); std::remove_copy_if (myints,myints+7,myvector2.begin(),IsOdd); std::cout << "myvector2 contains:"; for (std::vector<int>::iterator it=myvector2.begin(); it!=myvector2.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; pend = std::remove_if (pbegin, pend, IsOdd); // 10 30 10 ? ? ? ? ? // ^ ^ std::cout << "the range contains:"; for (int* p=pbegin; p!=pend; ++p) std::cout << ' ' << *p; std::cout << '\n'; return 0; } Output: myvector contains: 10 31 30 11 10 0 0 0 range contains: 10 31 30 11 10 myvector2 contains: 10 30 10 10 0 0 0 the range contains: 10 30 10 */ // unique and unique_copy template <class _InputIter, class _OutputIter, class _Tp> _OutputIter __unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, _Tp*) { _Tp __value = *__first; *__result = __value; while (++__first != __last) if (!(__value == *__first)) { __value = *__first; *++__result = __value; } return ++__result; } //若result类型为output_iterator_tag,则调用该函数 template <class _InputIter, class _OutputIter> inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, output_iterator_tag) { //判断first的value_type类型,根据不同类型调用不同函数 return __unique_copy(__first, __last, __result, __VALUE_TYPE(__first)); } //若result类型为forward_iterator_tag,则调用该函数 template <class _InputIter, class _ForwardIter> _ForwardIter __unique_copy(_InputIter __first, _InputIter __last, _ForwardIter __result, forward_iterator_tag) { *__result = *__first;//记录第一个元素 while (++__first != __last)//遍历区间 //若不存在相邻重复元素,则继续记录到目标区result if (!(*__result == *__first)) *++__result = *__first;//记录元素到目标区 return ++__result; } ////unique_copy将区间[first,last)内元素复制到以result开头的区间上,但是如果存在相邻重复元素时,只复制其中第一个元素 //和unique一样,这里也有两个版本 /* 函数原型: equality (1) template <class InputIterator, class OutputIterator> OutputIterator unique_copy (InputIterator first, InputIterator last, OutputIterator result); predicate (2) template <class InputIterator, class OutputIterator, class BinaryPredicate> OutputIterator unique_copy (InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred); */ //版本一 template <class _InputIter, class _OutputIter> inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, _EqualityComparable); if (__first == __last) return __result; //根据result迭代器的类型,调用不同的函数 return __unique_copy(__first, __last, __result, __ITERATOR_CATEGORY(__result)); } template <class _InputIter, class _OutputIter, class _BinaryPredicate, class _Tp> _OutputIter __unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, _BinaryPredicate __binary_pred, _Tp*) { __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, _Tp, _Tp); _Tp __value = *__first; *__result = __value; while (++__first != __last) if (!__binary_pred(__value, *__first)) { __value = *__first; *++__result = __value; } return ++__result; } template <class _InputIter, class _OutputIter, class _BinaryPredicate> inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, _BinaryPredicate __binary_pred, output_iterator_tag) { return __unique_copy(__first, __last, __result, __binary_pred, __VALUE_TYPE(__first)); } template <class _InputIter, class _ForwardIter, class _BinaryPredicate> _ForwardIter __unique_copy(_InputIter __first, _InputIter __last, _ForwardIter __result, _BinaryPredicate __binary_pred, forward_iterator_tag) { __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_InputIter>::value_type); *__result = *__first; while (++__first != __last) if (!__binary_pred(*__result, *__first)) *++__result = *__first; return ++__result; } //版本二 template <class _InputIter, class _OutputIter, class _BinaryPredicate> inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); if (__first == __last) return __result; //根据result迭代器的类型,调用不同的函数 return __unique_copy(__first, __last, __result, __binary_pred, __ITERATOR_CATEGORY(__result)); } //移除区间[first,last)相邻连续重复的元素 //unique有两个版本 //功能:Removes all but the first element from every consecutive group of equivalent elements in the range [first,last). /* 函数原型: equality (1):版本一采用operator== template <class ForwardIterator> ForwardIterator unique (ForwardIterator first, ForwardIterator last); predicate (2):版本二采用pred操作 template <class ForwardIterator, class BinaryPredicate> ForwardIterator unique (ForwardIterator first, ForwardIterator last, BinaryPredicate pred); */ //版本一 template <class _ForwardIter> _ForwardIter unique(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _EqualityComparable); __first = adjacent_find(__first, __last);//找出第一个相邻元素的起始位置 return unique_copy(__first, __last, __first);//调用unique_copy完成操作 } //版本二 template <class _ForwardIter, class _BinaryPredicate> _ForwardIter unique(_ForwardIter __first, _ForwardIter __last, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); __first = adjacent_find(__first, __last, __binary_pred);//找出第一个相邻元素的起始位置 return unique_copy(__first, __last, __first, __binary_pred);//调用unique_copy完成操作 } ~~~ 参考资料: 《STL源码剖析》侯捷
';

STL算法之merge合并算法

最后更新于:2022-04-01 15:51:34

### 前言   由于在前文的《[STL算法剖析](http://blog.csdn.net/chenhanzhun/article/details/39698523)》中,源码剖析非常多,不方便学习,也不方便以后复习,这里把这些算法进行归类,对他们单独的源码剖析进行讲解。本文介绍的STL算法中的merge合并算法。源码中介绍了函数merge、inplace_merge。并对这些函数的源码进行详细的剖析,并适当给出使用例子,具体详见下面源码剖析。 ### merge合并算法源码剖析 ~~~ // merge, with and without an explicitly supplied comparison function. //将两个已排序的区间[first1,last1)和区间[first2,last2)合并 /* 函数功能:Combines the elements in the sorted ranges [first1,last1) and [first2,last2), into a new range beginning at result with all its elements sorted. 函数原型: default (1) :版本一 template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); custom (2) :版本二 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); */ //版本一: template <class _InputIter1, class _InputIter2, class _OutputIter> _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); //两个序列都尚未到达尾端,则执行while循环 /* 情况1:若序列二元素较小,则记录到目标区,且移动序列二的迭代器,但是序列一的迭代器不变. 情况2:若序列一元素较小或相等,则记录到目标区,且移动序列一的迭代器,但是序列二的迭代器不变. 最后:把剩余元素的序列复制到目标区 */ while (__first1 != __last1 && __first2 != __last2) { //情况1 if (*__first2 < *__first1) {//若序列二元素较小 *__result = *__first2;//将元素记录到目标区 ++__first2;//移动迭代器 } //情况2 else {//若序列一元素较小或相等 *__result = *__first1;//将元素记录到目标区 ++__first1;//移动迭代器 } ++__result;//更新目标区位置,以便下次记录数据 } //若有序列到达尾端,则把没到达尾端的序列剩余元素复制到目标区 //此时,区间[first1,last1)和区间[first2,last2)至少一个必定为空 return copy(__first2, __last2, copy(__first1, __last1, __result)); } //版本二 template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare> _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter1>::value_type); while (__first1 != __last1 && __first2 != __last2) { if (__comp(*__first2, *__first1)) { *__result = *__first2; ++__first2; } else { *__result = *__first1; ++__first1; } ++__result; } return copy(__first2, __last2, copy(__first1, __last1, __result)); } //merge函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::merge, std::sort #include <vector> // std::vector int main () { int first[] = {5,10,15,20,25}; int second[] = {50,40,30,20,10}; std::vector<int> v(10); std::sort (first,first+5); std::sort (second,second+5); std::merge (first,first+5,second,second+5,v.begin()); std::cout << "The resulting vector contains:"; for (std::vector<int>::iterator it=v.begin(); it!=v.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: The resulting vector contains: 5 10 10 15 20 20 25 30 40 50 */ // inplace_merge and its auxiliary functions. //版本一的辅助函数,无缓冲区的操作 template <class _BidirectionalIter, class _Distance> void __merge_without_buffer(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance __len1, _Distance __len2) { if (__len1 == 0 || __len2 == 0) return; if (__len1 + __len2 == 2) { if (*__middle < *__first) iter_swap(__first, __middle); return; } _BidirectionalIter __first_cut = __first; _BidirectionalIter __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) { __len11 = __len1 / 2; advance(__first_cut, __len11); __second_cut = lower_bound(__middle, __last, *__first_cut); distance(__middle, __second_cut, __len22); } else { __len22 = __len2 / 2; advance(__second_cut, __len22); __first_cut = upper_bound(__first, __middle, *__second_cut); distance(__first, __first_cut, __len11); } _BidirectionalIter __new_middle = rotate(__first_cut, __middle, __second_cut); __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22); __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22); } template <class _BidirectionalIter, class _Distance, class _Compare> void __merge_without_buffer(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance __len1, _Distance __len2, _Compare __comp) { if (__len1 == 0 || __len2 == 0) return; if (__len1 + __len2 == 2) { if (__comp(*__middle, *__first)) iter_swap(__first, __middle); return; } _BidirectionalIter __first_cut = __first; _BidirectionalIter __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) { __len11 = __len1 / 2; advance(__first_cut, __len11); __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); distance(__middle, __second_cut, __len22); } else { __len22 = __len2 / 2; advance(__second_cut, __len22); __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); distance(__first, __first_cut, __len11); } _BidirectionalIter __new_middle = rotate(__first_cut, __middle, __second_cut); __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22, __comp); __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22, __comp); } //版本一的辅助函数,有缓冲区的操作 template <class _BidirectionalIter1, class _BidirectionalIter2, class _Distance> _BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first, _BidirectionalIter1 __middle, _BidirectionalIter1 __last, _Distance __len1, _Distance __len2, _BidirectionalIter2 __buffer, _Distance __buffer_size) { _BidirectionalIter2 __buffer_end; if (__len1 > __len2 && __len2 <= __buffer_size) {//缓冲区足够放置序列二 __buffer_end = copy(__middle, __last, __buffer); copy_backward(__first, __middle, __last); return copy(__buffer, __buffer_end, __first); } else if (__len1 <= __buffer_size) {//缓冲区足够放置序列一 __buffer_end = copy(__first, __middle, __buffer); copy(__middle, __last, __first); return copy_backward(__buffer, __buffer_end, __last); } else//若缓冲区仍然不够,则调用STL算法rotate,不使用缓冲区 return rotate(__first, __middle, __last); } template <class _BidirectionalIter1, class _BidirectionalIter2, class _BidirectionalIter3> _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, _BidirectionalIter3 __result) { if (__first1 == __last1) return copy_backward(__first2, __last2, __result); if (__first2 == __last2) return copy_backward(__first1, __last1, __result); --__last1; --__last2; while (true) { if (*__last2 < *__last1) { *--__result = *__last1; if (__first1 == __last1) return copy_backward(__first2, ++__last2, __result); --__last1; } else { *--__result = *__last2; if (__first2 == __last2) return copy_backward(__first1, ++__last1, __result); --__last2; } } } template <class _BidirectionalIter1, class _BidirectionalIter2, class _BidirectionalIter3, class _Compare> _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, _BidirectionalIter3 __result, _Compare __comp) { if (__first1 == __last1) return copy_backward(__first2, __last2, __result); if (__first2 == __last2) return copy_backward(__first1, __last1, __result); --__last1; --__last2; while (true) { if (__comp(*__last2, *__last1)) { *--__result = *__last1; if (__first1 == __last1) return copy_backward(__first2, ++__last2, __result); --__last1; } else { *--__result = *__last2; if (__first2 == __last2) return copy_backward(__first1, ++__last1, __result); --__last2; } } } //版本一的辅助函数,有缓冲区的操作 template <class _BidirectionalIter, class _Distance, class _Pointer> void __merge_adaptive(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance __len1, _Distance __len2, _Pointer __buffer, _Distance __buffer_size) { if (__len1 <= __len2 && __len1 <= __buffer_size) { //case1:把序列一放在缓冲区 _Pointer __buffer_end = copy(__first, __middle, __buffer); //直接调用归并函数merge merge(__buffer, __buffer_end, __middle, __last, __first); } else if (__len2 <= __buffer_size) { //case2:把序列二放在缓冲区 _Pointer __buffer_end = copy(__middle, __last, __buffer); __merge_backward(__first, __middle, __buffer, __buffer_end, __last); } else {//case3:缓冲区不足放置任何一个序列 _BidirectionalIter __first_cut = __first; _BidirectionalIter __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) {//若序列一比较长 __len11 = __len1 / 2;//计算序列一的一半 advance(__first_cut, __len11);//让first_cut指向序列一的中间位置 //找出*__first_cut在[middle,last)区间中的第一个不小于*__first_cut的元素位置 __second_cut = lower_bound(__middle, __last, *__first_cut); //计算middle到__second_cut之间的距离,保存在__len22 distance(__middle, __second_cut, __len22); } else {//若序列二比较长 __len22 = __len2 / 2;//计算序列二的一半 advance(__second_cut, __len22);//让__second_cut指向序列二的中间位置 //找出*__second_cut在[first,middle)区间中的第一个大于*__second_cut的元素位置 __first_cut = upper_bound(__first, __middle, *__second_cut); //计算__first到__first_cut之间的距离,保存在__len11 distance(__first, __first_cut, __len11); } _BidirectionalIter __new_middle = __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, __len22, __buffer, __buffer_size); //对左半段递归调用 __merge_adaptive(__first, __first_cut, __new_middle, __len11, __len22, __buffer, __buffer_size); //对右半段递归调用 __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22, __buffer, __buffer_size); } } template <class _BidirectionalIter, class _Distance, class _Pointer, class _Compare> void __merge_adaptive(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance __len1, _Distance __len2, _Pointer __buffer, _Distance __buffer_size, _Compare __comp) { if (__len1 <= __len2 && __len1 <= __buffer_size) { _Pointer __buffer_end = copy(__first, __middle, __buffer); merge(__buffer, __buffer_end, __middle, __last, __first, __comp); } else if (__len2 <= __buffer_size) { _Pointer __buffer_end = copy(__middle, __last, __buffer); __merge_backward(__first, __middle, __buffer, __buffer_end, __last, __comp); } else { _BidirectionalIter __first_cut = __first; _BidirectionalIter __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) { __len11 = __len1 / 2; advance(__first_cut, __len11); __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); distance(__middle, __second_cut, __len22); } else { __len22 = __len2 / 2; advance(__second_cut, __len22); __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); distance(__first, __first_cut, __len11); } _BidirectionalIter __new_middle = __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, __len22, __buffer, __buffer_size); __merge_adaptive(__first, __first_cut, __new_middle, __len11, __len22, __buffer, __buffer_size, __comp); __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22, __buffer, __buffer_size, __comp); } } //版本一的辅助函数 template <class _BidirectionalIter, class _Tp, class _Distance> inline void __inplace_merge_aux(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Tp*, _Distance*) { _Distance __len1 = 0; distance(__first, __middle, __len1);//计算序列一的长度 _Distance __len2 = 0; distance(__middle, __last, __len2);//计算序列二的长度 //使用暂时缓冲区 _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); if (__buf.begin() == 0)//若缓冲区配置失败 //则调用不使用缓冲区的合并操作 __merge_without_buffer(__first, __middle, __last, __len1, __len2); else//若分配成功 //则调用具有缓冲区的合并操作 __merge_adaptive(__first, __middle, __last, __len1, __len2, __buf.begin(), _Distance(__buf.size())); } template <class _BidirectionalIter, class _Tp, class _Distance, class _Compare> inline void __inplace_merge_aux(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Tp*, _Distance*, _Compare __comp) { _Distance __len1 = 0; distance(__first, __middle, __len1); _Distance __len2 = 0; distance(__middle, __last, __len2); _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); if (__buf.begin() == 0) __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp); else __merge_adaptive(__first, __middle, __last, __len1, __len2, __buf.begin(), _Distance(__buf.size()), __comp); } //将两个已排序的序列[first,middle)和[middle,last)合并成单一有序序列. //若原来是增序,现在也是递增排序,若原来是递减排序,现在也是递减排序 /* 函数功能:Merges two consecutive sorted ranges: [first,middle) and [middle,last), putting the result into the combined sorted range [first,last). 函数原型: default (1) :版本一 template <class BidirectionalIterator> void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); custom (2) :版本二 template <class BidirectionalIterator, class Compare> void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp); */ //版本一 template <class _BidirectionalIter> inline void inplace_merge(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last) { __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type, _LessThanComparable); if (__first == __middle || __middle == __last)//若有空序列,则之间返回 return; __inplace_merge_aux(__first, __middle, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } //版本二 template <class _BidirectionalIter, class _Compare> inline void inplace_merge(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Compare __comp) { __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_BidirectionalIter>::value_type, typename iterator_traits<_BidirectionalIter>::value_type); if (__first == __middle || __middle == __last) return; __inplace_merge_aux(__first, __middle, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first), __comp); } //inplace_merge函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::inplace_merge, std::sort, std::copy #include <vector> // std::vector int main () { int first[] = {5,10,15,20,25}; int second[] = {50,40,30,20,10}; std::vector<int> v(10); std::vector<int>::iterator it; std::sort (first,first+5); std::sort (second,second+5); it=std::copy (first, first+5, v.begin()); std::copy (second,second+5,it); std::inplace_merge (v.begin(),v.begin()+5,v.end()); std::cout << "The resulting vector contains:"; for (it=v.begin(); it!=v.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: The resulting vector contains: 5 10 10 15 20 20 25 30 40 50 */ ~~~ 参考资料: 《STL源码剖析》侯捷
';

STL算法之find查找算法

最后更新于:2022-04-01 15:51:32

### 前言   由于在前文的《[STL算法剖析](http://blog.csdn.net/chenhanzhun/article/details/39698523)》中,源码剖析非常多,不方便学习,也不方便以后复习,这里把这些算法进行归类,对他们单独的源码剖析进行讲解。本文介绍的STL算法中的find、search查找算法。在STL源码中有关算法的函数大部分在本文介绍,包含findand find_if、adjacent_find、search、search_n、lower_bound、upper_bound、equal_range、binary_search、find_first_of、find_end相关算法,下面对这些算法的源码进行了详细的剖析,并且适当给出应用例子,增加我们对其理解,方便我们使用这些算法。具体详见下面源码剖析。 ### 查找算法源码剖析 ~~~ // find and find_if. //查找区间[first,last)内元素第一个与value值相等的元素,并返回其位置 //其中find函数是采用默认的equality操作operator== //find_if是采用用户自行指定的操作pred //若find函数萃取出来的迭代器类型为输入迭代器input_iterator_tag,则调用此函数 template <class _InputIter, class _Tp> inline _InputIter find(_InputIter __first, _InputIter __last, const _Tp& __val, input_iterator_tag) {//若尚未到达区间的尾端,且未找到匹配的值,则继续查找 while (__first != __last && !(*__first == __val)) ++__first; //若找到匹配的值,则返回该位置 //若找不到,即到达区间尾端,此时first=last,则返回first return __first; } //若find_if函数萃取出来的迭代器类型为输入迭代器input_iterator_tag,则调用此函数 template <class _InputIter, class _Predicate> inline _InputIter find_if(_InputIter __first, _InputIter __last, _Predicate __pred, input_iterator_tag) {//若尚未到达区间的尾端,且未找到匹配的值,则继续查找 while (__first != __last && !__pred(*__first)) ++__first; //若找到匹配的值,则返回该位置 //若找不到,即到达区间尾端,此时first=last,则返回first return __first; } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION //若find函数萃取出来的迭代器类型为随机访问迭代器random_access_iterator_tag,则调用此函数 template <class _RandomAccessIter, class _Tp> _RandomAccessIter find(_RandomAccessIter __first, _RandomAccessIter __last, const _Tp& __val, random_access_iterator_tag) { typename iterator_traits<_RandomAccessIter>::difference_type __trip_count = (__last - __first) >> 2; for ( ; __trip_count > 0 ; --__trip_count) { if (*__first == __val) return __first; ++__first; if (*__first == __val) return __first; ++__first; if (*__first == __val) return __first; ++__first; if (*__first == __val) return __first; ++__first; } switch(__last - __first) { case 3: if (*__first == __val) return __first; ++__first; case 2: if (*__first == __val) return __first; ++__first; case 1: if (*__first == __val) return __first; ++__first; case 0: default: return __last; } } //若find_if函数萃取出来的迭代器类型为随机访问迭代器random_access_iterator_tag,则调用此函数 template <class _RandomAccessIter, class _Predicate> _RandomAccessIter find_if(_RandomAccessIter __first, _RandomAccessIter __last, _Predicate __pred, random_access_iterator_tag) { typename iterator_traits<_RandomAccessIter>::difference_type __trip_count = (__last - __first) >> 2; for ( ; __trip_count > 0 ; --__trip_count) { if (__pred(*__first)) return __first; ++__first; if (__pred(*__first)) return __first; ++__first; if (__pred(*__first)) return __first; ++__first; if (__pred(*__first)) return __first; ++__first; } switch(__last - __first) { case 3: if (__pred(*__first)) return __first; ++__first; case 2: if (__pred(*__first)) return __first; ++__first; case 1: if (__pred(*__first)) return __first; ++__first; case 0: default: return __last; } } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ /*find函数功能:Returns an iterator to the first element in the range [first,last) that compares equal to val. If no such element is found, the function returns last. find函数原型: template <class InputIterator, class T> InputIterator find (InputIterator first, InputIterator last, const T& val); */ //find函数对外接口 template <class _InputIter, class _Tp> inline _InputIter find(_InputIter __first, _InputIter __last, const _Tp& __val) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_InputIter>::value_type, _Tp); //首先萃取出first迭代器的类型,根据迭代器的类型调用不同的函数 return find(__first, __last, __val, __ITERATOR_CATEGORY(__first)); } /*find_if函数功能:Returns an iterator to the first element in the range [first,last) for which pred returns true. If no such element is found, the function returns last. find_if函数原型: template <class InputIterator, class UnaryPredicate> InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred); */ //find_if 函数对外接口 template <class _InputIter, class _Predicate> inline _InputIter find_if(_InputIter __first, _InputIter __last, _Predicate __pred) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_InputIter>::value_type); //首先萃取出first迭代器的类型,根据迭代器的类型调用不同的函数 return find_if(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); } //find和find_if函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::find_if #include <vector> // std::vector bool IsOdd (int i) { return ((i%2)==1); } int main () { std::vector<int> myvector; myvector.push_back(10); myvector.push_back(25); myvector.push_back(40); myvector.push_back(55); std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd); std::cout << "The first odd value is " << *it << '\n'; // using std::find with vector and iterator: it = find (myvector.begin(), myvector.end(), 40); if (it != myvector.end()) std::cout << "Element found in myvector: " << *it << '\n'; else std::cout << "Element not found in myints\n"; return 0; } Output: The first odd value is 25 Element found in myvector: 40 */ // adjacent_find. //查找区间[first,last)内第一次重复的相邻元素 //若存在返回相邻元素的第一个元素位置 //若不存在返回last位置 /*该函数有两个版本:第一版本是默认操作operator==;第二版本是用户指定的二元操作pred 函数对外接口的原型: equality (1):默认操作是operator== template <class ForwardIterator> ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last); predicate (2):用户指定的二元操作pred template <class ForwardIterator, class BinaryPredicate> ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last, BinaryPredicate pred); */ //版本一:默认操作是operator== template <class _ForwardIter> _ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _EqualityComparable); /* 情况1:若输入区间为空,则直接返回尾端last; 情况2:若输入区间不为空,且存在相邻重复元素,则返回相邻元素的第一个元素的位置; 情况3:若输入区间不为空,但是不存在相邻重复元素,则直接返回尾端last; */ //情况1: if (__first == __last)//若输入区间为空 return __last;//直接返回last //情况2: _ForwardIter __next = __first;//定义当前位置的下一个位置(即当前元素的相邻元素) while(++__next != __last) {//若还没到达尾端,执行while循环 if (*__first == *__next)//相邻元素值相等,则找到相邻重复元素 return __first;//返回第一个元素的位置 __first = __next;//若暂时找不到,则继续找,直到到达区间尾端 } //情况3: return __last;//直接返回尾端last } //版本二:用户指定的二元操作pred //实现过程和版本一一样,只是判断规则不同 template <class _ForwardIter, class _BinaryPredicate> _ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return __last; _ForwardIter __next = __first; while(++__next != __last) { //如果找到相邻元素符合用户指定条件,就返回第一元素位置 if (__binary_pred(*__first, *__next)) return __first; __first = __next; } return __last; } //adjacent_find函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::adjacent_find #include <vector> // std::vector bool myfunction (int i, int j) { return (i==j); } int main () { int myints[] = {5,20,5,30,30,20,10,10,20}; std::vector<int> myvector (myints,myints+8); std::vector<int>::iterator it; // using default comparison: it = std::adjacent_find (myvector.begin(), myvector.end()); if (it!=myvector.end()) std::cout << "the first pair of repeated elements are: " << *it << '\n'; //using predicate comparison: it = std::adjacent_find (++it, myvector.end(), myfunction); if (it!=myvector.end()) std::cout << "the second pair of repeated elements are: " << *it << '\n'; return 0; } Output: the first pair of repeated elements are: 30 the second pair of repeated elements are: 10 */ // search. //在序列一[first1,last1)所涵盖的区间中,查找序列二[first2,last2)的首次出现点 //该查找函数有两个版本: //版本一:使用默认的equality操作operator== //版本二:用户根据需要自行指定操作规则 /*search函数功能:Searches the range [first1,last1) for the first occurrence of the sequence defined by [first2,last2), and returns an iterator to its first element, or last1 if no occurrences are found. search函数的原型: equality (1):版本一 template <class ForwardIterator1, class ForwardIterator2> ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); predicate (2):版本二 template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); */ //版本一:使用默认的equality操作operator== template <class _ForwardIter1, class _ForwardIter2> _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2) { __STL_REQUIRES(_ForwardIter1, _ForwardIterator); __STL_REQUIRES(_ForwardIter2, _ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; // Test for a pattern of length 1. _ForwardIter2 __tmp(__first2); ++__tmp; if (__tmp == __last2) return find(__first1, __last1, *__first2); // General case. _ForwardIter2 __p1, __p; __p1 = __first2; ++__p1; _ForwardIter1 __current = __first1; while (__first1 != __last1) {//若还没到达区间尾端 __first1 = find(__first1, __last1, *__first2);//查找*first2在区间[first1,last1)首次出现的位置 if (__first1 == __last1)//若在[first1,last1)中不存在*first2,即在[first1,last1)不存在子序列[first2,last2) return __last1;//则直接返回区间尾端 __p = __p1; __current = __first1; if (++__current == __last1)//若[first1,last1)只有一个元素,即序列[first1,last1)小于序列[first2,last2) return __last1;//不可能成为其子序列,返回last1 while (*__current == *__p) {//若两个序列相对应的值相同 if (++__p == __last2)//若序列[first2,last2)只有两个元素,且与序列一匹配 return __first1;//则返回匹配的首次位置 if (++__current == __last1)//若第一个序列小于第二个序列 return __last1;//返回last1 } ++__first1; } return __first1; } //版本二:用户根据需要自行指定操作规则 template <class _ForwardIter1, class _ForwardIter2, class _BinaryPred> _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2, _BinaryPred __predicate) { __STL_REQUIRES(_ForwardIter1, _ForwardIterator); __STL_REQUIRES(_ForwardIter2, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPred, bool, typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; // Test for a pattern of length 1. _ForwardIter2 __tmp(__first2); ++__tmp; if (__tmp == __last2) { while (__first1 != __last1 && !__predicate(*__first1, *__first2)) ++__first1; return __first1; } // General case. _ForwardIter2 __p1, __p; __p1 = __first2; ++__p1; _ForwardIter1 __current = __first1; while (__first1 != __last1) { while (__first1 != __last1) { if (__predicate(*__first1, *__first2)) break; ++__first1; } while (__first1 != __last1 && !__predicate(*__first1, *__first2)) ++__first1; if (__first1 == __last1) return __last1; __p = __p1; __current = __first1; if (++__current == __last1) return __last1; while (__predicate(*__current, *__p)) { if (++__p == __last2) return __first1; if (++__current == __last1) return __last1; } ++__first1; } return __first1; } // search_n. Search for __count consecutive copies of __val. //在序列[first,last)查找连续count个符合条件值value元素的位置 //该查找函数有两个版本: //版本一:使用默认的equality操作operator== //版本二:用户根据需要自行指定操作规则 /*search_n函数功能:Searches the range [first,last) for a sequence of count elements, each comparing equal to val (or for which pred returns true). search_n函数的原型: equality (1):版本一 template <class ForwardIterator, class Size, class T> ForwardIterator search_n (ForwardIterator first, ForwardIterator last, Size count, const T& val); predicate (2):版本二 template <class ForwardIterator, class Size, class T, class BinaryPredicate> ForwardIterator search_n ( ForwardIterator first, ForwardIterator last, Size count, const T& val, BinaryPredicate pred ); */ //版本一:使用默认的equality操作operator== template <class _ForwardIter, class _Integer, class _Tp> _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, _Integer __count, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _EqualityComparable); __STL_REQUIRES(_Tp, _EqualityComparable); if (__count <= 0) return __first; else {//首先查找value第一次出现的位置 __first = find(__first, __last, __val); while (__first != __last) {//若出现的位置不是区间尾端 _Integer __n = __count - 1;//更新个数,下面只需查找n=count-1个连续相同value即可 _ForwardIter __i = __first; ++__i;//从当前位置的下一个位置开始查找 //若没有到达区间尾端,且个数n大于0,且区间元素与value值相等 while (__i != __last && __n != 0 && *__i == __val) { ++__i;//继续查找 --__n;//减少查找的次数,因为已经找到value再次出现 } if (__n == 0)//若区间尚未到达尾端,但是count个value已经查找到 return __first;//则输出查找到的首次出现value的位置 else __first = find(__i, __last, __val);//若尚未找到连续count个value值的位置,则找出value下次出现的位置,并准备下一次while循环 } return __last; } } //版本二:用户根据需要自行指定操作规则 template <class _ForwardIter, class _Integer, class _Tp, class _BinaryPred> _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, _Integer __count, const _Tp& __val, _BinaryPred __binary_pred) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPred, bool, typename iterator_traits<_ForwardIter>::value_type, _Tp); if (__count <= 0) return __first; else { while (__first != __last) { if (__binary_pred(*__first, __val)) break; ++__first; } while (__first != __last) { _Integer __n = __count - 1; _ForwardIter __i = __first; ++__i; while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) { ++__i; --__n; } if (__n == 0) return __first; else { while (__i != __last) { if (__binary_pred(*__i, __val)) break; ++__i; } __first = __i; } } return __last; } } //search和search_n函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::search_n #include <vector> // std::vector bool mypredicate (int i, int j) { return (i==j); } int main () { int myints[]={10,20,30,30,20,10,10,20}; std::vector<int> myvector (myints,myints+8); std::vector<int>::iterator it; // using default comparison: it = std::search_n (myvector.begin(), myvector.end(), 2, 30); if (it!=myvector.end()) std::cout << "two 30s found at position " << (it-myvector.begin()) << '\n'; else std::cout << "match not found\n"; // using predicate comparison: it = std::search_n (myvector.begin(), myvector.end(), 2, 10, mypredicate); if (it!=myvector.end()) std::cout << "two 10s found at position " << int(it-myvector.begin()) << '\n'; else std::cout << "match not found\n"; int needle1[] = {10,20}; // using default comparison: it = std::search (myvector.begin(), myvector.end(), needle1, needle1+2); if (it!=myvector.end()) std::cout << "needle1 found at position " << (it-myvector.begin()) << '\n'; else std::cout << "needle1 not found\n"; // using predicate comparison: int needle2[] = {30,20,10}; it = std::search (myvector.begin(), myvector.end(), needle2, needle2+3, mypredicate); if (it!=myvector.end()) std::cout << "needle2 found at position " << (it-myvector.begin()) << '\n'; else std::cout << "needle2 not found\n"; return 0; } Output: two 30s found at position 2 two 10s found at position 5 needle1 found at position 0 needle2 found at position 3 */ // Binary search (lower_bound, upper_bound, equal_range, binary_search). template <class _ForwardIter, class _Tp, class _Distance> _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Distance*) { _Distance __len = 0; distance(__first, __last, __len);//求取整个区间的长度len _Distance __half; _ForwardIter __middle;//定义区间的中间迭代器 while (__len > 0) {//若区间不为空,则在区间[first,last)开始查找value值 __half = __len >> 1;//向右移一位,相当于除以2,即取区间的中间值 __middle = __first;//middle初始化为区间的起始位置 advance(__middle, __half);//middle向后移half位,此时middle为区间的中间值 if (*__middle < __val) {//将value值与中间值比较,即是二分查找,若中间值小于value,则继续查找右半部分 //下面两行令first指向middle的下一个位置 __first = __middle; ++__first; __len = __len - __half - 1;//调整查找区间的长度 } else __len = __half;//否则查找左半部分 } return __first; } //在已排序区间[first,last)查找value值 //若该区间存在与value相等的元素,则返回指向第一个与value相等的迭代器 //若该区间不存在与value相等的元素,则返回指向第一个不小于value值的迭代器 //若该区间的任何元素都比value值小,则返回last /* 函数功能:Returns an iterator pointing to the first element in the range [first,last) which does not compare less than val. 函数原型: default (1) :版本一采用operator<比较 template <class ForwardIterator, class T> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val); custom (2) :版本二采用仿函数comp比较规则 template <class ForwardIterator, class T, class Compare> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); */ //版本一 template <class _ForwardIter, class _Tp> inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_REQUIRES(_Tp, _LessThanComparable); return __lower_bound(__first, __last, __val, __DISTANCE_TYPE(__first)); } template <class _ForwardIter, class _Tp, class _Compare, class _Distance> _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp, _Distance*) { _Distance __len = 0; distance(__first, __last, __len);//求取整个区间的长度len _Distance __half; _ForwardIter __middle;//定义区间的中间迭代器 while (__len > 0) {//若区间不为空,则在区间[first,last)开始查找value值 __half = __len >> 1;//向右移一位,相当于除以2,即取区间的中间值 __middle = __first;//middle初始化为区间的起始位置 advance(__middle, __half);//middle向后移half位,此时middle为区间的中间值 if (__comp(*__middle, __val)) {//若comp判断为true,则继续在右半部分查找 //下面两行令first指向middle的下一个位置 __first = __middle; ++__first; __len = __len - __half - 1;//调整查找区间的长度 } else __len = __half;//否则查找左半部分 } return __first; } //版本二: template <class _ForwardIter, class _Tp, class _Compare> inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); return __lower_bound(__first, __last, __val, __comp, __DISTANCE_TYPE(__first)); } template <class _ForwardIter, class _Tp, class _Distance> _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Distance*) { _Distance __len = 0; distance(__first, __last, __len);//求取整个区间的长度len _Distance __half; _ForwardIter __middle;//定义区间的中间迭代器 while (__len > 0) {//若区间不为空,则在区间[first,last)开始查找value值 __half = __len >> 1;//向右移一位,相当于除以2,即取区间的中间值 __middle = __first;//middle初始化为区间的起始位置 advance(__middle, __half);//middle向后移half位,此时middle为区间的中间值 if (__val < *__middle)//若value小于中间元素值 __len = __half;//查找左半部分 else { //下面两行令first指向middle的下一个位置 __first = __middle; ++__first; __len = __len - __half - 1;//更新len的值 } } return __first; } //在已排序区间[first,last)查找value值 //返回大于value值的第一个元素的迭代器 /* 函数功能:Returns an iterator pointing to the first element in the range [first,last) which compares greater than val. 函数原型: default (1) :版本一采用operator<比较 template <class ForwardIterator, class T> ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val); custom (2) :版本二采用仿函数comp比较规则 template <class ForwardIterator, class T, class Compare> ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); */ //版本一 template <class _ForwardIter, class _Tp> inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_REQUIRES(_Tp, _LessThanComparable); return __upper_bound(__first, __last, __val, __DISTANCE_TYPE(__first)); } template <class _ForwardIter, class _Tp, class _Compare, class _Distance> _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp, _Distance*) { _Distance __len = 0; distance(__first, __last, __len); _Distance __half; _ForwardIter __middle; while (__len > 0) { __half = __len >> 1; __middle = __first; advance(__middle, __half); if (__comp(__val, *__middle)) __len = __half; else { __first = __middle; ++__first; __len = __len - __half - 1; } } return __first; } //版本二 template <class _ForwardIter, class _Tp, class _Compare> inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); return __upper_bound(__first, __last, __val, __comp, __DISTANCE_TYPE(__first)); } //函数举例 /* #include <iostream> // std::cout #include <algorithm> // std::lower_bound, std::upper_bound, std::sort #include <vector> // std::vector int main () { int myints[] = {10,20,30,30,20,10,10,20}; std::vector<int> v(myints,myints+8); // 10 20 30 30 20 10 10 20 std::sort (v.begin(), v.end()); // 10 10 10 20 20 20 30 30 std::vector<int>::iterator low,up; low=std::lower_bound (v.begin(), v.end(), 20); // ^ up= std::upper_bound (v.begin(), v.end(), 20); // ^ std::cout << "lower_bound at position " << (low- v.begin()) << '\n'; std::cout << "upper_bound at position " << (up - v.begin()) << '\n'; return 0; } Output: lower_bound at position 3 upper_bound at position 6 */ template <class _ForwardIter, class _Tp, class _Distance> pair<_ForwardIter, _ForwardIter> __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Distance*) { _Distance __len = 0; distance(__first, __last, __len);//计算区间的长度len _Distance __half; _ForwardIter __middle, __left, __right; while (__len > 0) {//若区间非空 __half = __len >> 1;//len右移一位,相等于除以2,即half为区间的长度的一半 __middle = __first;//初始化middle的值 advance(__middle, __half);//前进middle位置,使其指向区间中间位置 if (*__middle < __val) {//若指定元素value大于中间元素值,则在右半部分继续查找 //下面两行使first指向middle的下一个位置,即右半区间的起始位置 __first = __middle; ++__first; __len = __len - __half - 1;//更新待查找区间的长度 } else if (__val < *__middle)//若指定元素value小于中间元素值,则在左半部分继续查找 __len = __half;//更新待查找区间的长度 else {//若指定元素value等于中间元素值 //在前半部分找lower_bound位置 __left = lower_bound(__first, __middle, __val); advance(__first, __len); //在后半部分找upper_bound __right = upper_bound(++__middle, __first, __val); return pair<_ForwardIter, _ForwardIter>(__left, __right);//返回pair对象,第一个迭代器为left,第二个迭代器为right } } return pair<_ForwardIter, _ForwardIter>(__first, __first); } //查找区间与value相等的相邻重复元素的起始位置和结束位置 //注意:[first,last)是已排序,思想还是采用二分查找法 //同样也有两个版本 /* 函数功能:Returns the bounds of the subrange that includes all the elements of the range [first,last) with values equivalent to val. 函数原型: default (1) :版本一默认operator< template <class ForwardIterator, class T> pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const T& val); custom (2) :版本二采用仿函数comp template <class ForwardIterator, class T, class Compare> pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); */ //版本一 template <class _ForwardIter, class _Tp> inline pair<_ForwardIter, _ForwardIter> equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_REQUIRES(_Tp, _LessThanComparable); return __equal_range(__first, __last, __val, __DISTANCE_TYPE(__first)); } template <class _ForwardIter, class _Tp, class _Compare, class _Distance> pair<_ForwardIter, _ForwardIter> __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp, _Distance*) { _Distance __len = 0; distance(__first, __last, __len); _Distance __half; _ForwardIter __middle, __left, __right; while (__len > 0) { __half = __len >> 1; __middle = __first; advance(__middle, __half); if (__comp(*__middle, __val)) { __first = __middle; ++__first; __len = __len - __half - 1; } else if (__comp(__val, *__middle)) __len = __half; else { __left = lower_bound(__first, __middle, __val, __comp); advance(__first, __len); __right = upper_bound(++__middle, __first, __val, __comp); return pair<_ForwardIter, _ForwardIter>(__left, __right); } } return pair<_ForwardIter, _ForwardIter>(__first, __first); } //版本二 template <class _ForwardIter, class _Tp, class _Compare> inline pair<_ForwardIter, _ForwardIter> equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); return __equal_range(__first, __last, __val, __comp, __DISTANCE_TYPE(__first)); } //equal_range函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::equal_range, std::sort #include <vector> // std::vector bool mygreater (int i,int j) { return (i>j); } int main () { int myints[] = {10,20,30,30,20,10,10,20}; std::vector<int> v(myints,myints+8); // 10 20 30 30 20 10 10 20 std::pair<std::vector<int>::iterator,std::vector<int>::iterator> bounds; // using default comparison: std::sort (v.begin(), v.end()); // 10 10 10 20 20 20 30 30 bounds=std::equal_range (v.begin(), v.end(), 20); // ^ ^ std::cout << "bounds at positions " << (bounds.first - v.begin()); std::cout << " and " << (bounds.second - v.begin()) << '\n'; // using "mygreater" as comp: std::sort (v.begin(), v.end(), mygreater); // 30 30 20 20 20 10 10 10 bounds=std::equal_range (v.begin(), v.end(), 20, mygreater); // ^ ^ std::cout << "bounds at positions " << (bounds.first - v.begin()); std::cout << " and " << (bounds.second - v.begin()) << '\n'; return 0; } Output: bounds at positions 3 and 6 bounds at positions 2 and 5 */ //二分查找法 //注意:[first,last)是已排序 //同样也有两个版本 /* 函数功能:Returns true if any element in the range [first,last) is equivalent to val, and false otherwise. 函数原型: default (1) :版本一默认operator< template <class ForwardIterator, class T> bool binary_search (ForwardIterator first, ForwardIterator last, const T& val); custom (2) :版本二采用仿函数comp template <class ForwardIterator, class T, class Compare> bool binary_search (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); */ template <class _ForwardIter, class _Tp> bool binary_search(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_REQUIRES(_Tp, _LessThanComparable); _ForwardIter __i = lower_bound(__first, __last, __val);//调用二分查找函数,并返回不小于value值的第一个迭代器位置i return __i != __last && !(__val < *__i); } template <class _ForwardIter, class _Tp, class _Compare> bool binary_search(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); _ForwardIter __i = lower_bound(__first, __last, __val, __comp);//调用二分查找函数,并返回不小于value值的第一个迭代器位置i return __i != __last && !__comp(__val, *__i); } // find_first_of, with and without an explicitly supplied comparison function. //以[first2,last2)区间内的某些元素为查找目标,寻找他们在[first1,last1)区间首次出现的位置 //find_first_of函数有两个版本: //版本一:提供默认的equality操作operator== //版本二:提供用户自行指定的操作规则comp /* 函数功能:Returns an iterator to the first element in the range [first1,last1) that matches any of the elements in [first2,last2). If no such element is found, the function returns last1. 函数原型: equality (1):版本一 template <class ForwardIterator1, class ForwardIterator2> ForwardIterator1 find_first_of (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); predicate (2):版本二 template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 find_first_of (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); */ //版本一:提供默认的equality操作operator== template <class _InputIter, class _ForwardIter> _InputIter find_first_of(_InputIter __first1, _InputIter __last1, _ForwardIter __first2, _ForwardIter __last2) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_InputIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); for ( ; __first1 != __last1; ++__first1) //若序列一不为空,则遍历序列一,每次指定一个元素 //以下,根据序列二的每个元素 for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) if (*__first1 == *__iter)//若序列一的元素等于序列二的元素,则表示找到 return __first1;//返回找到的位置 return __last1;//否则没找到 } //版本二:提供用户自行指定的操作规则comp template <class _InputIter, class _ForwardIter, class _BinaryPredicate> _InputIter find_first_of(_InputIter __first1, _InputIter __last1, _ForwardIter __first2, _ForwardIter __last2, _BinaryPredicate __comp) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_InputIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); for ( ; __first1 != __last1; ++__first1) for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) if (__comp(*__first1, *__iter)) return __first1; return __last1; } //find_first_of函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::find_first_of #include <vector> // std::vector #include <cctype> // std::tolower bool comp_case_insensitive (char c1, char c2) { return (std::tolower(c1)==std::tolower(c2)); } int main () { int mychars[] = {'a','b','c','A','B','C'}; std::vector<char> haystack (mychars,mychars+6); std::vector<char>::iterator it; int needle[] = {'A','B','C'}; // using default comparison: it = find_first_of (haystack.begin(), haystack.end(), needle, needle+3); if (it!=haystack.end()) std::cout << "The first match is: " << *it << '\n'; // using predicate comparison: it = find_first_of (haystack.begin(), haystack.end(), needle, needle+3, comp_case_insensitive); if (it!=haystack.end()) std::cout << "The first match is: " << *it << '\n'; return 0; } Output: The first match is: A The first match is: a */ // find_end, with and without an explicitly supplied comparison function. // Search [first2, last2) as a subsequence in [first1, last1), and return // the *last* possible match. Note that find_end for bidirectional iterators // is much faster than for forward iterators. // find_end for forward iterators. //若萃取出来的迭代器类型为正向迭代器forward_iterator_tag,则调用此函数 template <class _ForwardIter1, class _ForwardIter2> _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2, forward_iterator_tag, forward_iterator_tag) { if (__first2 == __last2)//若第二个区间为空 return __last1;//则直接返回第一个区间的尾端 else { _ForwardIter1 __result = __last1; while (1) { //以下利用search函数查找出某个子序列的首次出现点;若找不到直接返回last1 _ForwardIter1 __new_result = search(__first1, __last1, __first2, __last2); if (__new_result == __last1)//若返回的位置为尾端,则表示没找到 return __result;//返回last1 else {//若在[first1,last1)中找到[first2,last2)首次出现的位置,继续准备下一次查找 __result = __new_result;//更新返回的位置 __first1 = __new_result;//更新查找的起始位置 ++__first1;//确定正确查找起始位置 } } } } //版本二:指定规则 template <class _ForwardIter1, class _ForwardIter2, class _BinaryPredicate> _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2, forward_iterator_tag, forward_iterator_tag, _BinaryPredicate __comp) { if (__first2 == __last2) return __last1; else { _ForwardIter1 __result = __last1; while (1) { _ForwardIter1 __new_result = search(__first1, __last1, __first2, __last2, __comp); if (__new_result == __last1) return __result; else { __result = __new_result; __first1 = __new_result; ++__first1; } } } } // find_end for bidirectional iterators. Requires partial specialization. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION //若萃取出来的迭代器类型为双向迭代器bidirectional_iterator_tag,则调用此函数 template <class _BidirectionalIter1, class _BidirectionalIter2> _BidirectionalIter1 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag) { __STL_REQUIRES(_BidirectionalIter1, _BidirectionalIterator); __STL_REQUIRES(_BidirectionalIter2, _BidirectionalIterator); //利用反向迭代器很快就可以找到 typedef reverse_iterator<_BidirectionalIter1> _RevIter1; typedef reverse_iterator<_BidirectionalIter2> _RevIter2; _RevIter1 __rlast1(__first1); _RevIter2 __rlast2(__first2); //查找时将序列一和序列二逆方向 _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, _RevIter2(__last2), __rlast2); if (__rresult == __rlast1)//表示没找到 return __last1; else {//找到了 _BidirectionalIter1 __result = __rresult.base();//转会正常迭代器 advance(__result, -distance(__first2, __last2));//调整回到子序列的起始位置 return __result; } } //版本二:指定规则comp template <class _BidirectionalIter1, class _BidirectionalIter2, class _BinaryPredicate> _BidirectionalIter1 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag, _BinaryPredicate __comp) { __STL_REQUIRES(_BidirectionalIter1, _BidirectionalIterator); __STL_REQUIRES(_BidirectionalIter2, _BidirectionalIterator); typedef reverse_iterator<_BidirectionalIter1> _RevIter1; typedef reverse_iterator<_BidirectionalIter2> _RevIter2; _RevIter1 __rlast1(__first1); _RevIter2 __rlast2(__first2); _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, _RevIter2(__last2), __rlast2, __comp); if (__rresult == __rlast1) return __last1; else { _BidirectionalIter1 __result = __rresult.base(); advance(__result, -distance(__first2, __last2)); return __result; } } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // Dispatching functions for find_end. //find_end函数有两个版本: //版本一:提供默认的equality操作operator== //版本二:提供用户自行指定的操作规则comp //注意:这里也有偏特化的知识 /*函数功能:Searches the range [first1,last1) for the last occurrence of the sequence defined by [first2,last2), and returns an iterator to its first element, or last1 if no occurrences are found. 函数原型: equality (1):版本一 template <class ForwardIterator1, class ForwardIterator2> ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); predicate (2):版本二 template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); */ //对外接口的版本一 template <class _ForwardIter1, class _ForwardIter2> inline _ForwardIter1 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2) { __STL_REQUIRES(_ForwardIter1, _ForwardIterator); __STL_REQUIRES(_ForwardIter2, _ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); //首先通过iterator_traits萃取出first1和first2的迭代器类型 //根据不同的迭代器类型调用不同的函数 return __find_end(__first1, __last1, __first2, __last2, __ITERATOR_CATEGORY(__first1), __ITERATOR_CATEGORY(__first2)); } //对外接口的版本一 template <class _ForwardIter1, class _ForwardIter2, class _BinaryPredicate> inline _ForwardIter1 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2, _BinaryPredicate __comp) { __STL_REQUIRES(_ForwardIter1, _ForwardIterator); __STL_REQUIRES(_ForwardIter2, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); //首先通过iterator_traits萃取出first1和first2的迭代器类型 //根据不同的迭代器类型调用不同的函数 return __find_end(__first1, __last1, __first2, __last2, __ITERATOR_CATEGORY(__first1), __ITERATOR_CATEGORY(__first2), __comp); } //find_end函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::find_end #include <vector> // std::vector bool myfunction (int i, int j) { return (i==j); } int main () { int myints[] = {1,2,3,4,5,1,2,3,4,5}; std::vector<int> haystack (myints,myints+10); int needle1[] = {1,2,3}; // using default comparison: std::vector<int>::iterator it; it = std::find_end (haystack.begin(), haystack.end(), needle1, needle1+3); if (it!=haystack.end()) std::cout << "needle1 last found at position " << (it-haystack.begin()) << '\n'; int needle2[] = {4,5,1}; // using predicate comparison: it = std::find_end (haystack.begin(), haystack.end(), needle2, needle2+3, myfunction); if (it!=haystack.end()) std::cout << "needle2 last found at position " << (it-haystack.begin()) << '\n'; return 0; } Output: needle1 found at position 5 needle2 found at position 3 */ ~~~ 参考资料: 《STL源码剖析》侯捷
';

STL算法之sort排序算法

最后更新于:2022-04-01 15:51:30

### 前言   由于在前文的《[STL算法剖析](http://blog.csdn.net/chenhanzhun/article/details/39698523)》中,源码剖析非常多,不方便学习,也不方便以后复习,这里把这些算法进行归类,对他们单独的源码剖析进行讲解。本文介绍的STL算法中的sort排序算法,SGI STL中的排序算法不是简单的快速排序,而是交叉利用各种排序:堆排序、插入排序和快速排序;这样做的目的是提高效率,针对数据量比较大的采用快速排序,数据量比较小的可以采用堆排序或插入排序。本文介绍了有关排序的算法random_shuffle、partition、stable_partition、sort、stable_sort、partial_sort、partial_sort_copy、nth_element;注意:STL的sort排序算法的迭代器必须是随机访问迭代器。 ### sort排序算法剖析 ~~~ // Return a random number in the range [0, __n). This function encapsulates // whether we're using rand (part of the standard C library) or lrand48 // (not standard, but a much better choice whenever it's available). template <class _Distance> inline _Distance __random_number(_Distance __n) { #ifdef __STL_NO_DRAND48 return rand() % __n; #else return lrand48() % __n; #endif } // random_shuffle //将区间[first,last)内的元素随机重排 //两个版本的不同是随机数的取得 //版本一是使用内部随机数产生器 //版本二是使用一个会产生随机数的仿函数 /* 函数功能:Rearranges the elements in the range [first,last) randomly. 函数原型: generator by default (1) template <class RandomAccessIterator> void random_shuffle (RandomAccessIterator first, RandomAccessIterator last); specific generator (2) template <class RandomAccessIterator, class RandomNumberGenerator> void random_shuffle (RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& gen); */ //版本一 template <class _RandomAccessIter> inline void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); if (__first == __last) return; for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) iter_swap(__i, __first + __random_number((__i - __first) + 1)); } //版本二 template <class _RandomAccessIter, class _RandomNumberGenerator> void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last, _RandomNumberGenerator& __rand) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); if (__first == __last) return; for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) iter_swap(__i, __first + __rand((__i - __first) + 1)); } // random_sample and random_sample_n (extensions, not part of the standard). template <class _ForwardIter, class _OutputIter, class _Distance> _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, _OutputIter __out, const _Distance __n) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); _Distance __remaining = 0; distance(__first, __last, __remaining); _Distance __m = min(__n, __remaining); while (__m > 0) { if (__random_number(__remaining) < __m) { *__out = *__first; ++__out; --__m; } --__remaining; ++__first; } return __out; } template <class _ForwardIter, class _OutputIter, class _Distance, class _RandomNumberGenerator> _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, _OutputIter __out, const _Distance __n, _RandomNumberGenerator& __rand) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_UNARY_FUNCTION_CHECK(_RandomNumberGenerator, _Distance, _Distance); _Distance __remaining = 0; distance(__first, __last, __remaining); _Distance __m = min(__n, __remaining); while (__m > 0) { if (__rand(__remaining) < __m) { *__out = *__first; ++__out; --__m; } --__remaining; ++__first; } return __out; } template <class _InputIter, class _RandomAccessIter, class _Distance> _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, _RandomAccessIter __out, const _Distance __n) { _Distance __m = 0; _Distance __t = __n; for ( ; __first != __last && __m < __n; ++__m, ++__first) __out[__m] = *__first; while (__first != __last) { ++__t; _Distance __M = __random_number(__t); if (__M < __n) __out[__M] = *__first; ++__first; } return __out + __m; } template <class _InputIter, class _RandomAccessIter, class _RandomNumberGenerator, class _Distance> _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, _RandomAccessIter __out, _RandomNumberGenerator& __rand, const _Distance __n) { __STL_UNARY_FUNCTION_CHECK(_RandomNumberGenerator, _Distance, _Distance); _Distance __m = 0; _Distance __t = __n; for ( ; __first != __last && __m < __n; ++__m, ++__first) __out[__m] = *__first; while (__first != __last) { ++__t; _Distance __M = __rand(__t); if (__M < __n) __out[__M] = *__first; ++__first; } return __out + __m; } template <class _InputIter, class _RandomAccessIter> inline _RandomAccessIter random_sample(_InputIter __first, _InputIter __last, _RandomAccessIter __out_first, _RandomAccessIter __out_last) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); return __random_sample(__first, __last, __out_first, __out_last - __out_first); } template <class _InputIter, class _RandomAccessIter, class _RandomNumberGenerator> inline _RandomAccessIter random_sample(_InputIter __first, _InputIter __last, _RandomAccessIter __out_first, _RandomAccessIter __out_last, _RandomNumberGenerator& __rand) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); return __random_sample(__first, __last, __out_first, __rand, __out_last - __out_first); } // partition, stable_partition, and their auxiliary functions //若迭代器的类型为forward_iterator_tag,则调用此函数 template <class _ForwardIter, class _Predicate> _ForwardIter __partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, forward_iterator_tag) { if (__first == __last) return __first;//若为空,直接退出 while (__pred(*__first))//若pred出first的值为true if (++__first == __last) return __first;//先移动迭代器first,在判断是否到达尾端last _ForwardIter __next = __first;//继续判断 while (++__next != __last)//若下一个位置依然不是尾端 if (__pred(*__next)) {//继续pred出next的值,若为true swap(*__first, *__next);//交换值 ++__first;//继续下一位置 } return __first; } //若迭代器的类型为bidirectional_iterator_tag,则调用此函数 template <class _BidirectionalIter, class _Predicate> _BidirectionalIter __partition(_BidirectionalIter __first, _BidirectionalIter __last, _Predicate __pred, bidirectional_iterator_tag) { while (true) { while (true) if (__first == __last)//若为空 return __first;//直接退出 else if (__pred(*__first))//first的值符合不移动条件,则不移动该值 ++__first;//只移动迭代器 else//若头指针符合移动 break;//跳出循环 --__last;//尾指针回溯 while (true) if (__first == __last)//头指针等于尾指针 return __first;//操作结束 else if (!__pred(*__last))//尾指针的元素符合不移动操作 --__last;//至移动迭代器,并不移动具体元素 else//尾指针的元素符合移动操作 break;//跳出循环 iter_swap(__first, __last);//头尾指针交换元素 ++__first;//准备下一次循环 } } //将区间[first,last)的元素进行排序,被pred判断为true的放在区间的前段,判定为false的放在区间后段 //该算算可能会使元素的元素位置放生改变. /* 算法功能:Rearranges the elements from the range [first,last), in such a way that all the elements for which pred returns true precede all those for which it returns false. The iterator returned points to the first element of the second group. 算法原型: template <class BidirectionalIterator, class UnaryPredicate> BidirectionalIterator partition (BidirectionalIterator first, BidirectionalIterator last, UnaryPredicate pred); */ template <class _ForwardIter, class _Predicate> inline _ForwardIter partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_ForwardIter>::value_type); //首先萃取出迭代器first的类型,根据迭代器的类型调用不同的函数 return __partition(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); } //partition函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::partition #include <vector> // std::vector bool IsOdd (int i) { return (i%2)==1; } int main () { std::vector<int> myvector; // set some values: for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9 std::vector<int>::iterator bound; bound = std::partition (myvector.begin(), myvector.end(), IsOdd); // print out content: std::cout << "odd elements:"; for (std::vector<int>::iterator it=myvector.begin(); it!=bound; ++it) std::cout << ' ' << *it; std::cout << '\n'; std::cout << "even elements:"; for (std::vector<int>::iterator it=bound; it!=myvector.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: odd elements: 1 9 3 7 5 even elements: 6 4 8 2 */ template <class _ForwardIter, class _Predicate, class _Distance> _ForwardIter __inplace_stable_partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, _Distance __len) { if (__len == 1) return __pred(*__first) ? __last : __first; _ForwardIter __middle = __first; advance(__middle, __len / 2); return rotate(__inplace_stable_partition(__first, __middle, __pred, __len / 2), __middle, __inplace_stable_partition(__middle, __last, __pred, __len - __len / 2)); } template <class _ForwardIter, class _Pointer, class _Predicate, class _Distance> _ForwardIter __stable_partition_adaptive(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, _Distance __len, _Pointer __buffer, _Distance __buffer_size) { if (__len <= __buffer_size) { _ForwardIter __result1 = __first; _Pointer __result2 = __buffer; for ( ; __first != __last ; ++__first) if (__pred(*__first)) { *__result1 = *__first; ++__result1; } else { *__result2 = *__first; ++__result2; } copy(__buffer, __result2, __result1); return __result1; } else { _ForwardIter __middle = __first; advance(__middle, __len / 2); return rotate(__stable_partition_adaptive( __first, __middle, __pred, __len / 2, __buffer, __buffer_size), __middle, __stable_partition_adaptive( __middle, __last, __pred, __len - __len / 2, __buffer, __buffer_size)); } } template <class _ForwardIter, class _Predicate, class _Tp, class _Distance> inline _ForwardIter __stable_partition_aux(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, _Tp*, _Distance*) { _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last); if (__buf.size() > 0) return __stable_partition_adaptive(__first, __last, __pred, _Distance(__buf.requested_size()), __buf.begin(), __buf.size()); else return __inplace_stable_partition(__first, __last, __pred, _Distance(__buf.requested_size())); } template <class _ForwardIter, class _Predicate> inline _ForwardIter stable_partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return __first; else return __stable_partition_aux(__first, __last, __pred, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } //找出快速排序的枢纽位置 //版本一采用operator< template <class _RandomAccessIter, class _Tp> _RandomAccessIter __unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last, _Tp __pivot) { //找出枢纽轴的位置 //令头端迭代器向尾端方向移动,尾端迭代器向头端移动。 //当*first不小于枢纽值时,就停下来,当*last不大于枢纽值时也停下来,然后检测两个迭代器是否交错 //如果first仍然在左侧而last仍然在右侧,就交换两个元素,然后各自调整位置,向中央逼近,再继续执行相同的行为. //直到first和last两个迭代器交错,此时表示已找到枢纽轴位置即first所在的位置 while (true) { while (*__first < __pivot) ++__first;//first向尾端移动,直到遇到不小于枢纽值时,停止 --__last; while (__pivot < *__last) --__last;//last向头端移动,直到遇到不大于枢纽值时,停止 if (!(__first < __last))//检测两个迭代器是否交错 return __first;//交错,则此时已找到,即为first迭代器所指位置 iter_swap(__first, __last);//否则交换迭代器所指的元素 ++__first;//继续执行相同行为 } } //版本一采用__comp template <class _RandomAccessIter, class _Tp, class _Compare> _RandomAccessIter __unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last, _Tp __pivot, _Compare __comp) { while (true) { while (__comp(*__first, __pivot)) ++__first; --__last; while (__comp(__pivot, *__last)) --__last; if (!(__first < __last)) return __first; iter_swap(__first, __last); ++__first; } } const int __stl_threshold = 16; // sort() and its auxiliary functions. //__insertion_sort版本一的辅助函数 template <class _RandomAccessIter, class _Tp> void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) { _RandomAccessIter __next = __last; --__next; //__insertion_sort的内循环 //注意:一旦不再出现逆转对,循环就结束 while (__val < *__next) {//存在逆转对 *__last = *__next;//调整元素 __last = __next;//调整迭代器 --__next;//左移一个位置 } *__last = __val;//value的正确插入位置 } //__insertion_sort版本二的辅助函数 template <class _RandomAccessIter, class _Tp, class _Compare> void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, _Compare __comp) { _RandomAccessIter __next = __last; --__next; while (__comp(__val, *__next)) { *__last = *__next; __last = __next; --__next; } *__last = __val; } //__insertion_sort版本一的辅助函数 template <class _RandomAccessIter, class _Tp> inline void __linear_insert(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*) { _Tp __val = *__last;//记录尾元素 if (__val < *__first) {//尾元素比头元素还小 //将整个区间向右移一个位置 copy_backward(__first, __last, __last + 1); *__first = __val;//令头元素等于原先的尾元素 //以上两行命令的功能相等于交换两个元素 } else//尾元素不小于头元素 __unguarded_linear_insert(__last, __val); } //__insertion_sort版本二的辅助函数 template <class _RandomAccessIter, class _Tp, class _Compare> inline void __linear_insert(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Compare __comp) { _Tp __val = *__last; if (__comp(__val, *__first)) { copy_backward(__first, __last, __last + 1); *__first = __val; } else __unguarded_linear_insert(__last, __val, __comp); } //__insertion_sort以双层循环形式进行。外循环遍历整个序列,每次迭代决定出一个子区间; //内循环遍历子区间,将子区间内的每一个“逆转对”倒转过来,如果一旦不存在“逆转对”,表示排序完毕。 //“逆转对”概念:指任何两个迭代器i和j,i<j,而*i>*j. //版本一 template <class _RandomAccessIter> void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { if (__first == __last) return; //若区间为空,则退出 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)//外循环,遍历整个区间 //[first,i)形成的子空间 __linear_insert(__first, __i, __VALUE_TYPE(__first)); } //版本二 template <class _RandomAccessIter, class _Compare> void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { if (__first == __last) return; for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) __linear_insert(__first, __i, __VALUE_TYPE(__first), __comp); } template <class _RandomAccessIter, class _Tp> void __unguarded_insertion_sort_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*) { for (_RandomAccessIter __i = __first; __i != __last; ++__i) __unguarded_linear_insert(__i, _Tp(*__i)); } //sort版本一的辅助函数 template <class _RandomAccessIter> inline void __unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first)); } template <class _RandomAccessIter, class _Tp, class _Compare> void __unguarded_insertion_sort_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Compare __comp) { for (_RandomAccessIter __i = __first; __i != __last; ++__i) __unguarded_linear_insert(__i, _Tp(*__i), __comp); } template <class _RandomAccessIter, class _Compare> inline void __unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first), __comp); } //sort版本一的辅助函数 template <class _RandomAccessIter> void __final_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { if (__last - __first > __stl_threshold) {//判断元素个数是否大于16 //则把区间分割成两段,一端长度为16,另一端为剩余的长度 __insertion_sort(__first, __first + __stl_threshold); __unguarded_insertion_sort(__first + __stl_threshold, __last); } else//若不大于16,直接调用插入排序 __insertion_sort(__first, __last); } template <class _RandomAccessIter, class _Compare> void __final_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { if (__last - __first > __stl_threshold) { __insertion_sort(__first, __first + __stl_threshold, __comp); __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp); } else __insertion_sort(__first, __last, __comp); } //_lg()函数是用来控制分割恶化的情况 //该函数找出2^k <= n 的最大值k; //例如:n=7,得k=2; n=20,得k=4; n=8,得k=3; template <class _Size> inline _Size __lg(_Size __n) { _Size __k; for (__k = 0; __n != 1; __n >>= 1) ++__k; return __k; } //sort版本一的辅助函数 //参数__depth_limit表示最大的分割层数 template <class _RandomAccessIter, class _Tp, class _Size> void __introsort_loop(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Size __depth_limit) { //__stl_threshold为全局常量,其值为16 while (__last - __first > __stl_threshold) {//若区间长度大于16 if (__depth_limit == 0) {//表示分割恶化 partial_sort(__first, __last, __last);//转而调用堆排序heap_sort() return; } --__depth_limit; //计算分割点cut,枢纽值是采用首、尾、中央三个的中间值 _RandomAccessIter __cut = __unguarded_partition(__first, __last, _Tp(__median(*__first, *(__first + (__last - __first)/2), *(__last - 1)))); //对右半部分递归地进行排序 __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit); __last = __cut;//接下来对左半部分递归地进行排序 } } template <class _RandomAccessIter, class _Tp, class _Size, class _Compare> void __introsort_loop(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Size __depth_limit, _Compare __comp) { while (__last - __first > __stl_threshold) { if (__depth_limit == 0) { partial_sort(__first, __last, __last, __comp); return; } --__depth_limit; _RandomAccessIter __cut = __unguarded_partition(__first, __last, _Tp(__median(*__first, *(__first + (__last - __first)/2), *(__last - 1), __comp)), __comp); __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp); __last = __cut; } } //SGI STL的排序算法,迭代器参数的类型必须是随机访问迭代器_RandomAccessIter /* 函数功能:Sorts the elements in the range [first,last) into ascending order. 函数原型: default (1) :版本一采用默认的operator< template <class RandomAccessIterator> void sort (RandomAccessIterator first, RandomAccessIterator last); custom (2) :版本二采用仿函数comp template <class RandomAccessIterator, class Compare> void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp); */ //版本一 template <class _RandomAccessIter> inline void sort(_RandomAccessIter __first, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); //_lg()函数是用来控制分割恶化的情况 if (__first != __last) { __introsort_loop(__first, __last, __VALUE_TYPE(__first), __lg(__last - __first) * 2); //进行插入排序 __final_insertion_sort(__first, __last); } } //版本二 template <class _RandomAccessIter, class _Compare> inline void sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); if (__first != __last) { __introsort_loop(__first, __last, __VALUE_TYPE(__first), __lg(__last - __first) * 2, __comp); __final_insertion_sort(__first, __last, __comp); } } // stable_sort() and its auxiliary functions. template <class _RandomAccessIter> void __inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last) { if (__last - __first < 15) { __insertion_sort(__first, __last); return; } _RandomAccessIter __middle = __first + (__last - __first) / 2; __inplace_stable_sort(__first, __middle); __inplace_stable_sort(__middle, __last); __merge_without_buffer(__first, __middle, __last, __middle - __first, __last - __middle); } template <class _RandomAccessIter, class _Compare> void __inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { if (__last - __first < 15) { __insertion_sort(__first, __last, __comp); return; } _RandomAccessIter __middle = __first + (__last - __first) / 2; __inplace_stable_sort(__first, __middle, __comp); __inplace_stable_sort(__middle, __last, __comp); __merge_without_buffer(__first, __middle, __last, __middle - __first, __last - __middle, __comp); } template <class _RandomAccessIter1, class _RandomAccessIter2, class _Distance> void __merge_sort_loop(_RandomAccessIter1 __first, _RandomAccessIter1 __last, _RandomAccessIter2 __result, _Distance __step_size) { _Distance __two_step = 2 * __step_size; while (__last - __first >= __two_step) { __result = merge(__first, __first + __step_size, __first + __step_size, __first + __two_step, __result); __first += __two_step; } __step_size = min(_Distance(__last - __first), __step_size); merge(__first, __first + __step_size, __first + __step_size, __last, __result); } template <class _RandomAccessIter1, class _RandomAccessIter2, class _Distance, class _Compare> void __merge_sort_loop(_RandomAccessIter1 __first, _RandomAccessIter1 __last, _RandomAccessIter2 __result, _Distance __step_size, _Compare __comp) { _Distance __two_step = 2 * __step_size; while (__last - __first >= __two_step) { __result = merge(__first, __first + __step_size, __first + __step_size, __first + __two_step, __result, __comp); __first += __two_step; } __step_size = min(_Distance(__last - __first), __step_size); merge(__first, __first + __step_size, __first + __step_size, __last, __result, __comp); } const int __stl_chunk_size = 7; template <class _RandomAccessIter, class _Distance> void __chunk_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Distance __chunk_size) { while (__last - __first >= __chunk_size) { __insertion_sort(__first, __first + __chunk_size); __first += __chunk_size; } __insertion_sort(__first, __last); } template <class _RandomAccessIter, class _Distance, class _Compare> void __chunk_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Distance __chunk_size, _Compare __comp) { while (__last - __first >= __chunk_size) { __insertion_sort(__first, __first + __chunk_size, __comp); __first += __chunk_size; } __insertion_sort(__first, __last, __comp); } template <class _RandomAccessIter, class _Pointer, class _Distance> void __merge_sort_with_buffer(_RandomAccessIter __first, _RandomAccessIter __last, _Pointer __buffer, _Distance*) { _Distance __len = __last - __first; _Pointer __buffer_last = __buffer + __len; _Distance __step_size = __stl_chunk_size; __chunk_insertion_sort(__first, __last, __step_size); while (__step_size < __len) { __merge_sort_loop(__first, __last, __buffer, __step_size); __step_size *= 2; __merge_sort_loop(__buffer, __buffer_last, __first, __step_size); __step_size *= 2; } } template <class _RandomAccessIter, class _Pointer, class _Distance, class _Compare> void __merge_sort_with_buffer(_RandomAccessIter __first, _RandomAccessIter __last, _Pointer __buffer, _Distance*, _Compare __comp) { _Distance __len = __last - __first; _Pointer __buffer_last = __buffer + __len; _Distance __step_size = __stl_chunk_size; __chunk_insertion_sort(__first, __last, __step_size, __comp); while (__step_size < __len) { __merge_sort_loop(__first, __last, __buffer, __step_size, __comp); __step_size *= 2; __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp); __step_size *= 2; } } template <class _RandomAccessIter, class _Pointer, class _Distance> void __stable_sort_adaptive(_RandomAccessIter __first, _RandomAccessIter __last, _Pointer __buffer, _Distance __buffer_size) { _Distance __len = (__last - __first + 1) / 2; _RandomAccessIter __middle = __first + __len; if (__len > __buffer_size) { __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size); __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size); } else { __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0); __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0); } __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), _Distance(__last - __middle), __buffer, __buffer_size); } template <class _RandomAccessIter, class _Pointer, class _Distance, class _Compare> void __stable_sort_adaptive(_RandomAccessIter __first, _RandomAccessIter __last, _Pointer __buffer, _Distance __buffer_size, _Compare __comp) { _Distance __len = (__last - __first + 1) / 2; _RandomAccessIter __middle = __first + __len; if (__len > __buffer_size) { __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size, __comp); __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size, __comp); } else { __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0, __comp); __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0, __comp); } __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), _Distance(__last - __middle), __buffer, __buffer_size, __comp); } template <class _RandomAccessIter, class _Tp, class _Distance> inline void __stable_sort_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Distance*) { _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); if (buf.begin() == 0) __inplace_stable_sort(__first, __last); else __stable_sort_adaptive(__first, __last, buf.begin(), _Distance(buf.size())); } template <class _RandomAccessIter, class _Tp, class _Distance, class _Compare> inline void __stable_sort_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Distance*, _Compare __comp) { _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); if (buf.begin() == 0) __inplace_stable_sort(__first, __last, __comp); else __stable_sort_adaptive(__first, __last, buf.begin(), _Distance(buf.size()), __comp); } template <class _RandomAccessIter> inline void stable_sort(_RandomAccessIter __first, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); __stable_sort_aux(__first, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } template <class _RandomAccessIter, class _Compare> inline void stable_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __stable_sort_aux(__first, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first), __comp); } // partial_sort, partial_sort_copy, and auxiliary functions. //重新安排序列[first,last),使序列前半部分middle-first个最小元素以递增顺序排序,并将其置于[first,middle) //其余last-middle个元素不指定任何排序,并将其置于[middle,last) //注意:迭代器middle是在[first,last)范围之内 /* 函数功能:Rearranges the elements in the range [first,last), in such a way that the elements before middle are the smallest elements in the entire range and are sorted in ascending order, while the remaining elements are left without any specific order. 函数原型: default (1) 版本一 operator< template <class RandomAccessIterator> void partial_sort (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last); custom (2) 版本二 comp template <class RandomAccessIterator, class Compare> void partial_sort (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); */ template <class _RandomAccessIter, class _Tp> void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, _Tp*) { //利用heap的知识,在SGI STL中,是采用最大堆 //将[first,middle)区间的元素创建成最大堆 //再根据最大堆的性质,一个一个弹出堆,并将其保存,即堆排序 make_heap(__first, __middle);//创建最大堆,定义与<stl_heap.h>文件 //以下是在区间中[first,last)找出middle-first个最小元素 //这里的是将后半部分[middle,last)的元素依次与最大堆的根节点元素(即堆的最大元素)比较 //若小于堆的最大元素,则与堆的最大元素交换,并调整堆,使其依次成为最大堆 //若不小于堆的最大元素,则不作任何操作 for (_RandomAccessIter __i = __middle; __i < __last; ++__i) if (*__i < *__first) __pop_heap(__first, __middle, __i, _Tp(*__i), __DISTANCE_TYPE(__first)); sort_heap(__first, __middle);//对最大堆进行堆排序 } //版本一 template <class _RandomAccessIter> inline void partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first)); } template <class _RandomAccessIter, class _Tp, class _Compare> void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, _Tp*, _Compare __comp) { make_heap(__first, __middle, __comp); for (_RandomAccessIter __i = __middle; __i < __last; ++__i) if (__comp(*__i, *__first)) __pop_heap(__first, __middle, __i, _Tp(*__i), __comp, __DISTANCE_TYPE(__first)); sort_heap(__first, __middle, __comp); } //版本二 template <class _RandomAccessIter, class _Compare> inline void partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first), __comp); } //partial_sort_copy与partial_sort的实现机制是相同,只是partial_sort_copy将元素排序后放在以result起始的容器中 template <class _InputIter, class _RandomAccessIter, class _Distance, class _Tp> _RandomAccessIter __partial_sort_copy(_InputIter __first, _InputIter __last, _RandomAccessIter __result_first, _RandomAccessIter __result_last, _Distance*, _Tp*) { if (__result_first == __result_last) return __result_last; _RandomAccessIter __result_real_last = __result_first; while(__first != __last && __result_real_last != __result_last) { *__result_real_last = *__first; ++__result_real_last; ++__first; } make_heap(__result_first, __result_real_last); while (__first != __last) { if (*__first < *__result_first) __adjust_heap(__result_first, _Distance(0), _Distance(__result_real_last - __result_first), _Tp(*__first)); ++__first; } sort_heap(__result_first, __result_real_last); return __result_real_last; } template <class _InputIter, class _RandomAccessIter> inline _RandomAccessIter partial_sort_copy(_InputIter __first, _InputIter __last, _RandomAccessIter __result_first, _RandomAccessIter __result_last) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_CONVERTIBLE(typename iterator_traits<_InputIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, _LessThanComparable); return __partial_sort_copy(__first, __last, __result_first, __result_last, __DISTANCE_TYPE(__result_first), __VALUE_TYPE(__first)); } template <class _InputIter, class _RandomAccessIter, class _Compare, class _Distance, class _Tp> _RandomAccessIter __partial_sort_copy(_InputIter __first, _InputIter __last, _RandomAccessIter __result_first, _RandomAccessIter __result_last, _Compare __comp, _Distance*, _Tp*) { if (__result_first == __result_last) return __result_last; _RandomAccessIter __result_real_last = __result_first; while(__first != __last && __result_real_last != __result_last) { *__result_real_last = *__first; ++__result_real_last; ++__first; } make_heap(__result_first, __result_real_last, __comp); while (__first != __last) { if (__comp(*__first, *__result_first)) __adjust_heap(__result_first, _Distance(0), _Distance(__result_real_last - __result_first), _Tp(*__first), __comp); ++__first; } sort_heap(__result_first, __result_real_last, __comp); return __result_real_last; } template <class _InputIter, class _RandomAccessIter, class _Compare> inline _RandomAccessIter partial_sort_copy(_InputIter __first, _InputIter __last, _RandomAccessIter __result_first, _RandomAccessIter __result_last, _Compare __comp) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_CONVERTIBLE(typename iterator_traits<_InputIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); return __partial_sort_copy(__first, __last, __result_first, __result_last, __comp, __DISTANCE_TYPE(__result_first), __VALUE_TYPE(__first)); } // nth_element() and its auxiliary functions. //nth_element版本一辅助函数 template <class _RandomAccessIter, class _Tp> void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last, _Tp*) { while (__last - __first > 3) {//区间长度大于3 //获取分割点cut _RandomAccessIter __cut = __unguarded_partition(__first, __last, _Tp(__median(*__first, *(__first + (__last - __first)/2), *(__last - 1)))); if (__cut <= __nth)//若分割点小于指定位置,则nth位置在右半段 __first = __cut;//再对右半段进行分割 else //否则,对左半段进行分割 __last = __cut; } __insertion_sort(__first, __last); } //重新排序序列[first,last),使迭代器nth所指的元素,与“整个[first,last)序列完整排序后,同一位置的元素”同值. //此外,必须保证[nth,last)内的所有元素不小于[first,nth)内的元素,但是对于序列[first,nth)和序列[nth,last)内的元素的排序顺序不能确定. /* 函数功能:Rearranges the elements in the range [first,last), in such a way that the element at the nth position is the element that would be in that position in a sorted sequence. 函数原型: default (1) template <class RandomAccessIterator> void nth_element (RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last); custom (2) template <class RandomAccessIterator, class Compare> void nth_element (RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); */ //nth_element版本一 template <class _RandomAccessIter> inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); __nth_element(__first, __nth, __last, __VALUE_TYPE(__first)); } template <class _RandomAccessIter, class _Tp, class _Compare> void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last, _Tp*, _Compare __comp) { while (__last - __first > 3) { _RandomAccessIter __cut = __unguarded_partition(__first, __last, _Tp(__median(*__first, *(__first + (__last - __first)/2), *(__last - 1), __comp)), __comp); if (__cut <= __nth) __first = __cut; else __last = __cut; } __insertion_sort(__first, __last, __comp); } template <class _RandomAccessIter, class _Compare> inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __nth_element(__first, __nth, __last, __VALUE_TYPE(__first), __comp); } // is_sorted, a predicated testing whether a range is sorted in // nondescending order. This is an extension, not part of the C++ // standard. template <class _ForwardIter> bool is_sorted(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _LessThanComparable); if (__first == __last) return true; _ForwardIter __next = __first; for (++__next; __next != __last; __first = __next, ++__next) { if (*__next < *__first) return false; } return true; } template <class _ForwardIter, class _StrictWeakOrdering> bool is_sorted(_ForwardIter __first, _ForwardIter __last, _StrictWeakOrdering __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_StrictWeakOrdering, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return true; _ForwardIter __next = __first; for (++__next; __next != __last; __first = __next, ++__next) { if (__comp(*__next, *__first)) return false; } return true; } ~~~ 参考资料: 《STL源码剖析》侯捷
';

STL算法stl_algo.h

最后更新于:2022-04-01 15:51:27

### 前言   在前面的博文中剖析了STL的[数值算法](http://blog.csdn.net/chenhanzhun/article/details/39646237)、[基本算法](http://blog.csdn.net/chenhanzhun/article/details/39666289)和[set集合算法](http://blog.csdn.net/chenhanzhun/article/details/39669925),本文剖析STL其他的算法,例如排序算法、合并算法、查找算法等等。在剖析的时候,会针对函数给出一些例子说明函数的使用。源码出自SGI STL中的<stl_algo.h>文件。注:本文的源码非常多,可能后续博文会对这些算法进行归类分析。 ### STL算法剖析 ~~~ #ifndef __SGI_STL_INTERNAL_ALGO_H #define __SGI_STL_INTERNAL_ALGO_H #include <stl_heap.h>//这里包含堆的相关算法 //最大堆的相关算法已经介绍过了,有兴趣详见 //http://blog.csdn.net/chenhanzhun/article/details/39434491 // See concept_checks.h for the concept-checking macros // __STL_REQUIRES, __STL_CONVERTIBLE, etc. __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1209 #endif // __median (an extension, not present in the C++ standard). //函数功能:取三个元素a,b,c的中间值 //版本一采用默认的operator<操作 template <class _Tp> inline const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) { __STL_REQUIRES(_Tp, _LessThanComparable); if (__a < __b) if (__b < __c) return __b;//若a<b<c,则返回b else if (__a < __c) return __c;//若a<c<b,则返回c else return __a;//若c<a<b,则返回a else if (__a < __c) return __a;//若b<a<c,则返回a else if (__b < __c) return __c;//若b<c<a,则返回c else return __b;//否则返回b } //版本二采用仿函数comp比较 template <class _Tp, class _Compare> inline const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) { __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); if (__comp(__a, __b)) if (__comp(__b, __c)) return __b; else if (__comp(__a, __c)) return __c; else return __a; else if (__comp(__a, __c)) return __a; else if (__comp(__b, __c)) return __c; else return __b; } // for_each. Apply a function to every element of a range. //功能:Applies function fn to each of the elements in the range [first,last). //将仿函数f应用于[first,last)区间内的每一个元素上 //注:不能改变[first,last)内元素值 template <class _InputIter, class _Function> _Function for_each(_InputIter __first, _InputIter __last, _Function __f) { __STL_REQUIRES(_InputIter, _InputIterator); for ( ; __first != __last; ++__first) __f(*__first);//调用仿函数f return __f; } //for_each函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::for_each #include <vector> // std::vector void myfunction (int i) { // function: std::cout << ' ' << i; } struct myclass { // function object type: void operator() (int i) {std::cout << ' ' << i;} } myobject; int main () { std::vector<int> myvector; myvector.push_back(10); myvector.push_back(20); myvector.push_back(30); std::cout << "myvector contains:"; for_each (myvector.begin(), myvector.end(), myfunction); std::cout << '\n'; // or: std::cout << "myvector contains:"; for_each (myvector.begin(), myvector.end(), myobject); std::cout << '\n'; return 0; } Output: myvector contains: 10 20 30 myvector contains: 10 20 30 */ // find and find_if. //查找区间[first,last)内元素第一个与value值相等的元素,并返回其位置 //其中find函数是采用默认的equality操作operator== //find_if是采用用户自行指定的操作pred //若find函数萃取出来的迭代器类型为输入迭代器input_iterator_tag,则调用此函数 template <class _InputIter, class _Tp> inline _InputIter find(_InputIter __first, _InputIter __last, const _Tp& __val, input_iterator_tag) {//若尚未到达区间的尾端,且未找到匹配的值,则继续查找 while (__first != __last && !(*__first == __val)) ++__first; //若找到匹配的值,则返回该位置 //若找不到,即到达区间尾端,此时first=last,则返回first return __first; } //若find_if函数萃取出来的迭代器类型为输入迭代器input_iterator_tag,则调用此函数 template <class _InputIter, class _Predicate> inline _InputIter find_if(_InputIter __first, _InputIter __last, _Predicate __pred, input_iterator_tag) {//若尚未到达区间的尾端,且未找到匹配的值,则继续查找 while (__first != __last && !__pred(*__first)) ++__first; //若找到匹配的值,则返回该位置 //若找不到,即到达区间尾端,此时first=last,则返回first return __first; } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION //若find函数萃取出来的迭代器类型为随机访问迭代器random_access_iterator_tag,则调用此函数 template <class _RandomAccessIter, class _Tp> _RandomAccessIter find(_RandomAccessIter __first, _RandomAccessIter __last, const _Tp& __val, random_access_iterator_tag) { typename iterator_traits<_RandomAccessIter>::difference_type __trip_count = (__last - __first) >> 2; for ( ; __trip_count > 0 ; --__trip_count) { if (*__first == __val) return __first; ++__first; if (*__first == __val) return __first; ++__first; if (*__first == __val) return __first; ++__first; if (*__first == __val) return __first; ++__first; } switch(__last - __first) { case 3: if (*__first == __val) return __first; ++__first; case 2: if (*__first == __val) return __first; ++__first; case 1: if (*__first == __val) return __first; ++__first; case 0: default: return __last; } } //若find_if函数萃取出来的迭代器类型为随机访问迭代器random_access_iterator_tag,则调用此函数 template <class _RandomAccessIter, class _Predicate> _RandomAccessIter find_if(_RandomAccessIter __first, _RandomAccessIter __last, _Predicate __pred, random_access_iterator_tag) { typename iterator_traits<_RandomAccessIter>::difference_type __trip_count = (__last - __first) >> 2; for ( ; __trip_count > 0 ; --__trip_count) { if (__pred(*__first)) return __first; ++__first; if (__pred(*__first)) return __first; ++__first; if (__pred(*__first)) return __first; ++__first; if (__pred(*__first)) return __first; ++__first; } switch(__last - __first) { case 3: if (__pred(*__first)) return __first; ++__first; case 2: if (__pred(*__first)) return __first; ++__first; case 1: if (__pred(*__first)) return __first; ++__first; case 0: default: return __last; } } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ /*find函数功能:Returns an iterator to the first element in the range [first,last) that compares equal to val. If no such element is found, the function returns last. find函数原型: template <class InputIterator, class T> InputIterator find (InputIterator first, InputIterator last, const T& val); */ //find函数对外接口 template <class _InputIter, class _Tp> inline _InputIter find(_InputIter __first, _InputIter __last, const _Tp& __val) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_InputIter>::value_type, _Tp); //首先萃取出first迭代器的类型,根据迭代器的类型调用不同的函数 return find(__first, __last, __val, __ITERATOR_CATEGORY(__first)); } /*find_if函数功能:Returns an iterator to the first element in the range [first,last) for which pred returns true. If no such element is found, the function returns last. find_if函数原型: template <class InputIterator, class UnaryPredicate> InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred); */ //find_if 函数对外接口 template <class _InputIter, class _Predicate> inline _InputIter find_if(_InputIter __first, _InputIter __last, _Predicate __pred) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_InputIter>::value_type); //首先萃取出first迭代器的类型,根据迭代器的类型调用不同的函数 return find_if(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); } //find和find_if函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::find_if #include <vector> // std::vector bool IsOdd (int i) { return ((i%2)==1); } int main () { std::vector<int> myvector; myvector.push_back(10); myvector.push_back(25); myvector.push_back(40); myvector.push_back(55); std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd); std::cout << "The first odd value is " << *it << '\n'; // using std::find with vector and iterator: it = find (myvector.begin(), myvector.end(), 40); if (it != myvector.end()) std::cout << "Element found in myvector: " << *it << '\n'; else std::cout << "Element not found in myints\n"; return 0; } Output: The first odd value is 25 Element found in myvector: 40 */ // adjacent_find. //查找区间[first,last)内第一次重复的相邻元素 //若存在返回相邻元素的第一个元素位置 //若不存在返回last位置 /*该函数有两个版本:第一版本是默认操作operator==;第二版本是用户指定的二元操作pred 函数对外接口的原型: equality (1):默认操作是operator== template <class ForwardIterator> ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last); predicate (2):用户指定的二元操作pred template <class ForwardIterator, class BinaryPredicate> ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last, BinaryPredicate pred); */ //版本一:默认操作是operator== template <class _ForwardIter> _ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _EqualityComparable); /* 情况1:若输入区间为空,则直接返回尾端last; 情况2:若输入区间不为空,且存在相邻重复元素,则返回相邻元素的第一个元素的位置; 情况3:若输入区间不为空,但是不存在相邻重复元素,则直接返回尾端last; */ //情况1: if (__first == __last)//若输入区间为空 return __last;//直接返回last //情况2: _ForwardIter __next = __first;//定义当前位置的下一个位置(即当前元素的相邻元素) while(++__next != __last) {//若还没到达尾端,执行while循环 if (*__first == *__next)//相邻元素值相等,则找到相邻重复元素 return __first;//返回第一个元素的位置 __first = __next;//若暂时找不到,则继续找,直到到达区间尾端 } //情况3: return __last;//直接返回尾端last } //版本二:用户指定的二元操作pred //实现过程和版本一一样,只是判断规则不同 template <class _ForwardIter, class _BinaryPredicate> _ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return __last; _ForwardIter __next = __first; while(++__next != __last) { //如果找到相邻元素符合用户指定条件,就返回第一元素位置 if (__binary_pred(*__first, *__next)) return __first; __first = __next; } return __last; } //adjacent_find函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::adjacent_find #include <vector> // std::vector bool myfunction (int i, int j) { return (i==j); } int main () { int myints[] = {5,20,5,30,30,20,10,10,20}; std::vector<int> myvector (myints,myints+8); std::vector<int>::iterator it; // using default comparison: it = std::adjacent_find (myvector.begin(), myvector.end()); if (it!=myvector.end()) std::cout << "the first pair of repeated elements are: " << *it << '\n'; //using predicate comparison: it = std::adjacent_find (++it, myvector.end(), myfunction); if (it!=myvector.end()) std::cout << "the second pair of repeated elements are: " << *it << '\n'; return 0; } Output: the first pair of repeated elements are: 30 the second pair of repeated elements are: 10 */ // count and count_if. There are two version of each, one whose return type // type is void and one (present only if we have partial specialization) // whose return type is iterator_traits<_InputIter>::difference_type. The // C++ standard only has the latter version, but the former, which was present // in the HP STL, is retained for backward compatibility. //计算指定元素的个数 //SGI STL中提供两个版本,但是C++标准只提供一种版本 /*功能:Returns the number of elements in the range [first,last) that compare equal to val. C++标准只提供一种count原型: template <class InputIterator, class T> typename iterator_traits<InputIterator>::difference_type count (InputIterator first, InputIterator last, const T& val); */ //SGI STL提供的版本一count,不是C++标准:默认使用operator== template <class _InputIter, class _Tp, class _Size> void count(_InputIter __first, _InputIter __last, const _Tp& __value, _Size& __n) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, _EqualityComparable); __STL_REQUIRES(_Tp, _EqualityComparable); //将区间[first,last)内的元素和指定值value比较 //若没到达区间尾端,继续查找 for ( ; __first != __last; ++__first) if (*__first == __value)//若存在相等的值 ++__n;//计数器累加1 } /*功能:Returns the number of elements in the range [first,last) for which pred is true. C++标准只提供一种count_if原型: template <class InputIterator, class Predicate> typename iterator_traits<InputIterator>::difference_type count_if (InputIterator first, InputIterator last, UnaryPredicate pred); */ //SGI STL提供的版本一count_if,不是C++标准:默认使用operator== template <class _InputIter, class _Predicate, class _Size> void count_if(_InputIter __first, _InputIter __last, _Predicate __pred, _Size& __n) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_InputIter>::value_type); //将区间[first,last)内的元素和指定值value比较 //若没到达区间尾端,继续查找 for ( ; __first != __last; ++__first) if (__pred(*__first))//存在符合规则的元素 ++__n;//计数器累加1 } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION //SGI STL提供的版本二count,也C++标准提供的版本 template <class _InputIter, class _Tp> typename iterator_traits<_InputIter>::difference_type count(_InputIter __first, _InputIter __last, const _Tp& __value) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, _EqualityComparable); __STL_REQUIRES(_Tp, _EqualityComparable); typename iterator_traits<_InputIter>::difference_type __n = 0; //将区间[first,last)内的元素和指定值value比较 //若没到达区间尾端,继续查找 for ( ; __first != __last; ++__first) if (*__first == __value)//存在相等的元素 ++__n;//计数器累加1 return __n; } //SGI STL提供的版本二count_if,也C++标准提供的版本 template <class _InputIter, class _Predicate> typename iterator_traits<_InputIter>::difference_type count_if(_InputIter __first, _InputIter __last, _Predicate __pred) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_InputIter>::value_type); typename iterator_traits<_InputIter>::difference_type __n = 0; //将区间[first,last)内的元素和指定值value比较 //若没到达区间尾端,继续查找 for ( ; __first != __last; ++__first) if (__pred(*__first))//存在符合规则的元素 ++__n;//计数器累加1 return __n; } //下面针对count和count_if函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::count #include <vector> // std::vector bool IsOdd (int i) { return ((i%2)==1); } int main () { // counting elements in array: int myints[] = {10,20,31,30,21,10,11,20}; // 8 elements int mycount = std::count (myints, myints+8, 10); std::cout << "10 appears " << mycount << " times.\n"; // counting elements in container: std::vector<int> myvector (myints, myints+8); mycount = std::count (myvector.begin(), myvector.end(), 20); std::cout << "20 appears " << mycount << " times.\n"; mycount = count_if (myvector.begin(), myvector.end(), IsOdd); std::cout << "myvector contains " << mycount << " odd values.\n"; return 0; } Output: 10 appears 2 times. 20 appears 2 times. myvector contains 3 odd values. */ #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // search. //在序列一[first1,last1)所涵盖的区间中,查找序列二[first2,last2)的首次出现点 //该查找函数有两个版本: //版本一:使用默认的equality操作operator== //版本二:用户根据需要自行指定操作规则 /*search函数功能:Searches the range [first1,last1) for the first occurrence of the sequence defined by [first2,last2), and returns an iterator to its first element, or last1 if no occurrences are found. search函数的原型: equality (1):版本一 template <class ForwardIterator1, class ForwardIterator2> ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); predicate (2):版本二 template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); */ //版本一:使用默认的equality操作operator== template <class _ForwardIter1, class _ForwardIter2> _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2) { __STL_REQUIRES(_ForwardIter1, _ForwardIterator); __STL_REQUIRES(_ForwardIter2, _ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; // Test for a pattern of length 1. _ForwardIter2 __tmp(__first2); ++__tmp; if (__tmp == __last2) return find(__first1, __last1, *__first2); // General case. _ForwardIter2 __p1, __p; __p1 = __first2; ++__p1; _ForwardIter1 __current = __first1; while (__first1 != __last1) {//若还没到达区间尾端 __first1 = find(__first1, __last1, *__first2);//查找*first2在区间[first1,last1)首次出现的位置 if (__first1 == __last1)//若在[first1,last1)中不存在*first2,即在[first1,last1)不存在子序列[first2,last2) return __last1;//则直接返回区间尾端 __p = __p1; __current = __first1; if (++__current == __last1)//若[first1,last1)只有一个元素,即序列[first1,last1)小于序列[first2,last2) return __last1;//不可能成为其子序列,返回last1 while (*__current == *__p) {//若两个序列相对应的值相同 if (++__p == __last2)//若序列[first2,last2)只有两个元素,且与序列一匹配 return __first1;//则返回匹配的首次位置 if (++__current == __last1)//若第一个序列小于第二个序列 return __last1;//返回last1 } ++__first1; } return __first1; } //版本二:用户根据需要自行指定操作规则 template <class _ForwardIter1, class _ForwardIter2, class _BinaryPred> _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2, _BinaryPred __predicate) { __STL_REQUIRES(_ForwardIter1, _ForwardIterator); __STL_REQUIRES(_ForwardIter2, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPred, bool, typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; // Test for a pattern of length 1. _ForwardIter2 __tmp(__first2); ++__tmp; if (__tmp == __last2) { while (__first1 != __last1 && !__predicate(*__first1, *__first2)) ++__first1; return __first1; } // General case. _ForwardIter2 __p1, __p; __p1 = __first2; ++__p1; _ForwardIter1 __current = __first1; while (__first1 != __last1) { while (__first1 != __last1) { if (__predicate(*__first1, *__first2)) break; ++__first1; } while (__first1 != __last1 && !__predicate(*__first1, *__first2)) ++__first1; if (__first1 == __last1) return __last1; __p = __p1; __current = __first1; if (++__current == __last1) return __last1; while (__predicate(*__current, *__p)) { if (++__p == __last2) return __first1; if (++__current == __last1) return __last1; } ++__first1; } return __first1; } // search_n. Search for __count consecutive copies of __val. //在序列[first,last)查找连续count个符合条件值value元素的位置 //该查找函数有两个版本: //版本一:使用默认的equality操作operator== //版本二:用户根据需要自行指定操作规则 /*search_n函数功能:Searches the range [first,last) for a sequence of count elements, each comparing equal to val (or for which pred returns true). search_n函数的原型: equality (1):版本一 template <class ForwardIterator, class Size, class T> ForwardIterator search_n (ForwardIterator first, ForwardIterator last, Size count, const T& val); predicate (2):版本二 template <class ForwardIterator, class Size, class T, class BinaryPredicate> ForwardIterator search_n ( ForwardIterator first, ForwardIterator last, Size count, const T& val, BinaryPredicate pred ); */ //版本一:使用默认的equality操作operator== template <class _ForwardIter, class _Integer, class _Tp> _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, _Integer __count, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _EqualityComparable); __STL_REQUIRES(_Tp, _EqualityComparable); if (__count <= 0) return __first; else {//首先查找value第一次出现的位置 __first = find(__first, __last, __val); while (__first != __last) {//若出现的位置不是区间尾端 _Integer __n = __count - 1;//更新个数,下面只需查找n=count-1个连续相同value即可 _ForwardIter __i = __first; ++__i;//从当前位置的下一个位置开始查找 //若没有到达区间尾端,且个数n大于0,且区间元素与value值相等 while (__i != __last && __n != 0 && *__i == __val) { ++__i;//继续查找 --__n;//减少查找的次数,因为已经找到value再次出现 } if (__n == 0)//若区间尚未到达尾端,但是count个value已经查找到 return __first;//则输出查找到的首次出现value的位置 else __first = find(__i, __last, __val);//若尚未找到连续count个value值的位置,则找出value下次出现的位置,并准备下一次while循环 } return __last; } } //版本二:用户根据需要自行指定操作规则 template <class _ForwardIter, class _Integer, class _Tp, class _BinaryPred> _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, _Integer __count, const _Tp& __val, _BinaryPred __binary_pred) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPred, bool, typename iterator_traits<_ForwardIter>::value_type, _Tp); if (__count <= 0) return __first; else { while (__first != __last) { if (__binary_pred(*__first, __val)) break; ++__first; } while (__first != __last) { _Integer __n = __count - 1; _ForwardIter __i = __first; ++__i; while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) { ++__i; --__n; } if (__n == 0) return __first; else { while (__i != __last) { if (__binary_pred(*__i, __val)) break; ++__i; } __first = __i; } } return __last; } } //search和search_n函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::search_n #include <vector> // std::vector bool mypredicate (int i, int j) { return (i==j); } int main () { int myints[]={10,20,30,30,20,10,10,20}; std::vector<int> myvector (myints,myints+8); std::vector<int>::iterator it; // using default comparison: it = std::search_n (myvector.begin(), myvector.end(), 2, 30); if (it!=myvector.end()) std::cout << "two 30s found at position " << (it-myvector.begin()) << '\n'; else std::cout << "match not found\n"; // using predicate comparison: it = std::search_n (myvector.begin(), myvector.end(), 2, 10, mypredicate); if (it!=myvector.end()) std::cout << "two 10s found at position " << int(it-myvector.begin()) << '\n'; else std::cout << "match not found\n"; int needle1[] = {10,20}; // using default comparison: it = std::search (myvector.begin(), myvector.end(), needle1, needle1+2); if (it!=myvector.end()) std::cout << "needle1 found at position " << (it-myvector.begin()) << '\n'; else std::cout << "needle1 not found\n"; // using predicate comparison: int needle2[] = {30,20,10}; it = std::search (myvector.begin(), myvector.end(), needle2, needle2+3, mypredicate); if (it!=myvector.end()) std::cout << "needle2 found at position " << (it-myvector.begin()) << '\n'; else std::cout << "needle2 not found\n"; return 0; } Output: two 30s found at position 2 two 10s found at position 5 needle1 found at position 0 needle2 found at position 3 */ // swap_ranges //将区间[first1,last1)内的元素与“从first2开始,个数相同”的元素相互交换 //这两个序列可位于同一容器,或不同容器 //如果第二序列小于第一序列长度,或者两序列在同一容器且重叠,则结果未可预期 //Exchanges the values of each of the elements in the range [first1,last1) //with those of their respective elements in the range beginning at first2. template <class _ForwardIter1, class _ForwardIter2> _ForwardIter2 swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2) { __STL_REQUIRES(_ForwardIter1, _Mutable_ForwardIterator); __STL_REQUIRES(_ForwardIter2, _Mutable_ForwardIterator); __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter2>::value_type, typename iterator_traits<_ForwardIter1>::value_type); for ( ; __first1 != __last1; ++__first1, ++__first2)//遍历第一个序列 iter_swap(__first1, __first2);//交换迭代器所指的元素 return __first2; } //swap_ranges函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::swap_ranges #include <vector> // std::vector int main () { std::vector<int> foo (5,10); // foo: 10 10 10 10 10 std::vector<int> bar (5,33); // bar: 33 33 33 33 33 std::swap_ranges(foo.begin()+1, foo.end()-1, bar.begin()); // print out results of swap: std::cout << "foo contains:"; for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; std::cout << "bar contains:"; for (std::vector<int>::iterator it=bar.begin(); it!=bar.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: foo contains: 10 33 33 33 10 bar contains: 10 10 10 33 33 */ // transform //两个版本 /* 函数原型: unary operation(1):版本一 template <class InputIterator, class OutputIterator, class UnaryOperation> OutputIterator transform (InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperation op); binary operation(2):版本二 template <class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperation> OutputIterator transform (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op); 函数功能: (1) unary operation Applies op to each of the elements in the range [first1,last1) and stores the value returned by each operation in the range that begins at result. (2) binary operation Calls binary_op using each of the elements in the range [first1,last1) as first argument, and the respective argument in the range that begins at first2 as second argument. The value returned by each call is stored in the range that begins at result. */ //第一个版本:以仿函数opr作用于[first,last)中的每一个元素,并以其结果产生出一个新的序列 template <class _InputIter, class _OutputIter, class _UnaryOperation> _OutputIter transform(_InputIter __first, _InputIter __last, _OutputIter __result, _UnaryOperation __opr) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); for ( ; __first != __last; ++__first, ++__result) *__result = __opr(*__first); return __result; } //第二个版本:以仿函数binary_op作用于一双元素上(其中一个元素来自[first1,last1),另一个元素来自“从first2开始的序列”) //并以其结果产生出一个新的序列 template <class _InputIter1, class _InputIter2, class _OutputIter, class _BinaryOperation> _OutputIter transform(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _OutputIter __result, _BinaryOperation __binary_op) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result) *__result = __binary_op(*__first1, *__first2); return __result; } //transform函数举例: /* #include <vector> // std::vector #include <functional> // std::plus int op_increase (int i) { return ++i; } int main () { std::vector<int> foo; std::vector<int> bar; // set some values: for (int i=1; i<6; i++) foo.push_back (i*10); // foo: 10 20 30 40 50 bar.resize(foo.size()); // allocate space std::transform (foo.begin(), foo.end(), bar.begin(), op_increase); // bar: 11 21 31 41 51 std::cout << "bar contains:"; for (std::vector<int>::iterator it=bar.begin(); it!=bar.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; // std::plus adds together its two arguments: std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), std::plus<int>()); // foo: 21 41 61 81 101 std::cout << "foo contains:"; for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: bar contains: 11 21 31 41 51 foo contains: 21 41 61 81 101 */ // replace, replace_if, replace_copy, replace_copy_if //将区间[first,last)内的所有old_value都以new_value替代. template <class _ForwardIter, class _Tp> void replace(_ForwardIter __first, _ForwardIter __last, const _Tp& __old_value, const _Tp& __new_value) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_ForwardIter>::value_type, _Tp); __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); for ( ; __first != __last; ++__first) //将区间内所有old_value都以new_value替代. if (*__first == __old_value) *__first = __new_value; } //将区间[first,last)内的所有被pred判断为true的元素都以new_value替代. template <class _ForwardIter, class _Predicate, class _Tp> void replace_if(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, const _Tp& __new_value) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_ForwardIter>::value_type); for ( ; __first != __last; ++__first) if (__pred(*__first))//pred判断为true *__first = __new_value;//修改其值 } //将区间[first,last)内的所有old_value都以new_value替代.将新序列复制到result所指的容器中 //原始容器的内容并不会改变 template <class _InputIter, class _OutputIter, class _Tp> _OutputIter replace_copy(_InputIter __first, _InputIter __last, _OutputIter __result, const _Tp& __old_value, const _Tp& __new_value) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_InputIter>::value_type, _Tp); for ( ; __first != __last; ++__first, ++__result) *__result = *__first == __old_value ? __new_value : *__first; return __result; } //将区间[first,last)内的所有被pred判断为true的元素都以new_value替代.将新序列复制到result所指的容器中 //原始容器的内容并不会改变 template <class _InputIter, class _OutputIter, class _Predicate, class _Tp> _OutputIter replace_copy_if(_InputIter __first, _InputIter __last, _OutputIter __result, _Predicate __pred, const _Tp& __new_value) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_InputIter>::value_type); for ( ; __first != __last; ++__first, ++__result) *__result = __pred(*__first) ? __new_value : *__first; return __result; } // generate and generate_n //将仿函数gen的处理结果填充在[first, last)区间内所有元素上,所谓填写 //就是用迭代器所指元素的assignment操作 //注意:对于用户自定义类型要提供operator =() template <class _ForwardIter, class _Generator> void generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_GENERATOR_CHECK(_Generator, typename iterator_traits<_ForwardIter>::value_type); for ( ; __first != __last; ++__first)//遍历整个序列 *__first = __gen(); } //将仿函数gen的处理结果填充在first开始的n个元素上,所谓填写 //就是用迭代器所指元素的assignment操作 template <class _OutputIter, class _Size, class _Generator> _OutputIter generate_n(_OutputIter __first, _Size __n, _Generator __gen) { __STL_REQUIRES(_OutputIter, _OutputIterator); for ( ; __n > 0; --__n, ++__first)//只限于n个元素 *__first = __gen(); return __first; } //generate和generate_n函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::generate_n int current = 0; int UniqueNumber () { return ++current; } int main () { int myarray[9]; std::generate_n (myarray, 9, UniqueNumber); std::cout << "myarray contains:"; for (int i=0; i<9; ++i) std::cout << ' ' << myarray[i]; std::cout << '\n'; std::cout <<"the value of current: "<<current; std::cout << '\n'; std::vector<int> myvector (6); std::generate (myvector.begin(), myvector.end(), UniqueNumber); std::cout << "myvector contains:"; for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: myarray contains: 1 2 3 4 5 6 7 8 9 the value of current: 9 myvector contains: 10 11 12 13 14 15 */ // remove, remove_if, remove_copy, remove_copy_if //移除[first,last)区间内所有与value值相等的元素,并不是真正的从容器中删除这些元素(原容器的内容不会改变) //而是将结果复制到一个以result为起始位置的容器中。新容器可以与原容器重叠 template <class _InputIter, class _OutputIter, class _Tp> _OutputIter remove_copy(_InputIter __first, _InputIter __last, _OutputIter __result, const _Tp& __value) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_InputIter>::value_type, _Tp); for ( ; __first != __last; ++__first)//遍历容器 if (!(*__first == __value)) {//如果不相等 *__result = *__first;//赋值给新容器 ++__result;//新容器前进一个位置 } return __result; } //移除[first,last)区间内被仿函数pred判断为true的元素,并不是真正的从容器中删除这些元素(原容器的内容不会改变) //而是将结果复制到一个以result为起始位置的容器中。新容器可以与原容器重叠 template <class _InputIter, class _OutputIter, class _Predicate> _OutputIter remove_copy_if(_InputIter __first, _InputIter __last, _OutputIter __result, _Predicate __pred) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_InputIter>::value_type); for ( ; __first != __last; ++__first)//遍历容器 if (!__pred(*__first)) {//若pred判断为false *__result = *__first;//赋值给新容器 ++__result;//新容器前进一个位置 } return __result; } //移除[first,last)区间内所有与value值相等的元素,该操作不会改变容器大小,只是容器中元素值改变 //即移除之后,重新整理容器的内容 template <class _ForwardIter, class _Tp> _ForwardIter remove(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_ForwardIter>::value_type, _Tp); __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __first = find(__first, __last, __value);//利用顺序查找找出第一个与value相等的元素 _ForwardIter __i = __first; //下面调用remove_copy return __first == __last ? __first : remove_copy(++__i, __last, __first, __value); } //移除[first,last)区间内所有被pred判断为true的元素,该操作不会改变容器大小,只是容器中元素值改变 //即移除之后,重新整理容器的内容 template <class _ForwardIter, class _Predicate> _ForwardIter remove_if(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_ForwardIter>::value_type); __first = find_if(__first, __last, __pred);//利用顺序查找找出第一个与value相等的元素 _ForwardIter __i = __first; //下面调用remove_copy_if return __first == __last ? __first : remove_copy_if(++__i, __last, __first, __pred); } //上面四个移除函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::remove bool IsOdd (int i) { return ((i%2)==1); } int main () { int myints[] = {10,20,31,30,20,11,10,20}; // 10 20 31 30 20 11 10 20 std::vector<int> myvector (8); std::remove_copy (myints,myints+8,myvector.begin(),20); // 10 31 30 11 10 0 0 0 std::cout << "myvector contains:"; for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; // bounds of range: int* pbegin = myints; // ^ int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^ pend = std::remove (pbegin, pend, 20); // 10 31 30 11 10 ? ? ? // ^ ^ std::cout << "range contains:"; for (int* p=pbegin; p!=pend; ++p) std::cout << ' ' << *p; std::cout << '\n'; std::vector<int> myvector2 (7); std::remove_copy_if (myints,myints+7,myvector2.begin(),IsOdd); std::cout << "myvector2 contains:"; for (std::vector<int>::iterator it=myvector2.begin(); it!=myvector2.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; pend = std::remove_if (pbegin, pend, IsOdd); // 10 30 10 ? ? ? ? ? // ^ ^ std::cout << "the range contains:"; for (int* p=pbegin; p!=pend; ++p) std::cout << ' ' << *p; std::cout << '\n'; return 0; } Output: myvector contains: 10 31 30 11 10 0 0 0 range contains: 10 31 30 11 10 myvector2 contains: 10 30 10 10 0 0 0 the range contains: 10 30 10 */ // unique and unique_copy template <class _InputIter, class _OutputIter, class _Tp> _OutputIter __unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, _Tp*) { _Tp __value = *__first; *__result = __value; while (++__first != __last) if (!(__value == *__first)) { __value = *__first; *++__result = __value; } return ++__result; } //若result类型为output_iterator_tag,则调用该函数 template <class _InputIter, class _OutputIter> inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, output_iterator_tag) { //判断first的value_type类型,根据不同类型调用不同函数 return __unique_copy(__first, __last, __result, __VALUE_TYPE(__first)); } //若result类型为forward_iterator_tag,则调用该函数 template <class _InputIter, class _ForwardIter> _ForwardIter __unique_copy(_InputIter __first, _InputIter __last, _ForwardIter __result, forward_iterator_tag) { *__result = *__first;//记录第一个元素 while (++__first != __last)//遍历区间 //若不存在相邻重复元素,则继续记录到目标区result if (!(*__result == *__first)) *++__result = *__first;//记录元素到目标区 return ++__result; } ////unique_copy将区间[first,last)内元素复制到以result开头的区间上,但是如果存在相邻重复元素时,只复制其中第一个元素 //和unique一样,这里也有两个版本 /* 函数原型: equality (1) template <class InputIterator, class OutputIterator> OutputIterator unique_copy (InputIterator first, InputIterator last, OutputIterator result); predicate (2) template <class InputIterator, class OutputIterator, class BinaryPredicate> OutputIterator unique_copy (InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred); */ //版本一 template <class _InputIter, class _OutputIter> inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, _EqualityComparable); if (__first == __last) return __result; //根据result迭代器的类型,调用不同的函数 return __unique_copy(__first, __last, __result, __ITERATOR_CATEGORY(__result)); } template <class _InputIter, class _OutputIter, class _BinaryPredicate, class _Tp> _OutputIter __unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, _BinaryPredicate __binary_pred, _Tp*) { __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, _Tp, _Tp); _Tp __value = *__first; *__result = __value; while (++__first != __last) if (!__binary_pred(__value, *__first)) { __value = *__first; *++__result = __value; } return ++__result; } template <class _InputIter, class _OutputIter, class _BinaryPredicate> inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, _BinaryPredicate __binary_pred, output_iterator_tag) { return __unique_copy(__first, __last, __result, __binary_pred, __VALUE_TYPE(__first)); } template <class _InputIter, class _ForwardIter, class _BinaryPredicate> _ForwardIter __unique_copy(_InputIter __first, _InputIter __last, _ForwardIter __result, _BinaryPredicate __binary_pred, forward_iterator_tag) { __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_InputIter>::value_type); *__result = *__first; while (++__first != __last) if (!__binary_pred(*__result, *__first)) *++__result = *__first; return ++__result; } //版本二 template <class _InputIter, class _OutputIter, class _BinaryPredicate> inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); if (__first == __last) return __result; //根据result迭代器的类型,调用不同的函数 return __unique_copy(__first, __last, __result, __binary_pred, __ITERATOR_CATEGORY(__result)); } //移除区间[first,last)相邻连续重复的元素 //unique有两个版本 //功能:Removes all but the first element from every consecutive group of equivalent elements in the range [first,last). /* 函数原型: equality (1):版本一采用operator== template <class ForwardIterator> ForwardIterator unique (ForwardIterator first, ForwardIterator last); predicate (2):版本二采用pred操作 template <class ForwardIterator, class BinaryPredicate> ForwardIterator unique (ForwardIterator first, ForwardIterator last, BinaryPredicate pred); */ //版本一 template <class _ForwardIter> _ForwardIter unique(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _EqualityComparable); __first = adjacent_find(__first, __last);//找出第一个相邻元素的起始位置 return unique_copy(__first, __last, __first);//调用unique_copy完成操作 } //版本二 template <class _ForwardIter, class _BinaryPredicate> _ForwardIter unique(_ForwardIter __first, _ForwardIter __last, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); __first = adjacent_find(__first, __last, __binary_pred);//找出第一个相邻元素的起始位置 return unique_copy(__first, __last, __first, __binary_pred);//调用unique_copy完成操作 } // reverse and reverse_copy, and their auxiliary functions //若迭代器类型为bidirectional_iterator_tag,则调用此函数 template <class _BidirectionalIter> void __reverse(_BidirectionalIter __first, _BidirectionalIter __last, bidirectional_iterator_tag) { while (true) if (__first == __last || __first == --__last)//这里需注意,每次判断last迭代器都会后退一位 return; else iter_swap(__first++, __last);//单向交换迭代器所指的元素 } //若迭代器类型为random_access_iterator_tag,则调用此函数 template <class _RandomAccessIter> void __reverse(_RandomAccessIter __first, _RandomAccessIter __last, random_access_iterator_tag) { while (__first < __last)//遍历容器 iter_swap(__first++, --__last);//交换两端迭代器所指的元素 } //将序列[first,last)的所有元素在原容器中颠倒重排 template <class _BidirectionalIter> inline void reverse(_BidirectionalIter __first, _BidirectionalIter __last) { __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); //首先萃取出迭代器的类型 __reverse(__first, __last, __ITERATOR_CATEGORY(__first)); } //行为类似reverse,但产生的新序列会被置于以result指出的容器中 template <class _BidirectionalIter, class _OutputIter> _OutputIter reverse_copy(_BidirectionalIter __first, _BidirectionalIter __last, _OutputIter __result) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); while (__first != __last) {//遍历容器 --__last;//尾端前移一个位置 *__result = *__last;//result容器的起始位置元素值为原始容器尾端元素值 ++__result;//更新result,使其前进一个位置 } return __result; } // rotate and rotate_copy, and their auxiliary functions template <class _EuclideanRingElement> _EuclideanRingElement __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n) { while (__n != 0) { _EuclideanRingElement __t = __m % __n; __m = __n; __n = __t; } return __m; } //迭代器类型为forward_iterator_tag,调用此函数 template <class _ForwardIter, class _Distance> _ForwardIter __rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last, _Distance*, forward_iterator_tag) { if (__first == __middle) return __last; if (__last == __middle) return __first; _ForwardIter __first2 = __middle; do { swap(*__first++, *__first2++); if (__first == __middle) __middle = __first2; } while (__first2 != __last); _ForwardIter __new_middle = __first; __first2 = __middle; while (__first2 != __last) { swap (*__first++, *__first2++); if (__first == __middle) __middle = __first2; else if (__first2 == __last) __first2 = __middle; } return __new_middle; } //迭代器类型为bidirectional_iterator_tag,调用此函数 template <class _BidirectionalIter, class _Distance> _BidirectionalIter __rotate(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance*, bidirectional_iterator_tag) { __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); if (__first == __middle) return __last; if (__last == __middle) return __first; __reverse(__first, __middle, bidirectional_iterator_tag()); __reverse(__middle, __last, bidirectional_iterator_tag()); while (__first != __middle && __middle != __last) swap (*__first++, *--__last); if (__first == __middle) { __reverse(__middle, __last, bidirectional_iterator_tag()); return __last; } else { __reverse(__first, __middle, bidirectional_iterator_tag()); return __first; } } //迭代器类型为Random_iterator_tag,调用此函数 template <class _RandomAccessIter, class _Distance, class _Tp> _RandomAccessIter __rotate(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, _Distance *, _Tp *) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); _Distance __n = __last - __first; _Distance __k = __middle - __first; _Distance __l = __n - __k; _RandomAccessIter __result = __first + (__last - __middle); if (__k == 0) return __last; else if (__k == __l) { swap_ranges(__first, __middle, __middle); return __result; } _Distance __d = __gcd(__n, __k); for (_Distance __i = 0; __i < __d; __i++) { _Tp __tmp = *__first; _RandomAccessIter __p = __first; if (__k < __l) { for (_Distance __j = 0; __j < __l/__d; __j++) { if (__p > __first + __l) { *__p = *(__p - __l); __p -= __l; } *__p = *(__p + __k); __p += __k; } } else { for (_Distance __j = 0; __j < __k/__d - 1; __j ++) { if (__p < __last - __k) { *__p = *(__p + __k); __p += __k; } *__p = * (__p - __l); __p -= __l; } } *__p = __tmp; ++__first; } return __result; } //将区间[first,middle)内的元素和[middle,last)内的元素互换。minddle所指的元素会成为容器的第一个元素 //例如对序列{1,2,3,4,5,6,7},对元素3进行旋转操作,则结果为{3,4,5,6,7,1,2} template <class _ForwardIter> inline _ForwardIter rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); //萃取出迭代器的类型,根据迭代器的类型调用不同的函数 return __rotate(__first, __middle, __last, __DISTANCE_TYPE(__first), __ITERATOR_CATEGORY(__first)); } //将区间[first,middle)内的元素和[middle,last)内的元素互换。minddle所指的元素会成为新容器result的第一个元素 template <class _ForwardIter, class _OutputIter> _OutputIter rotate_copy(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last, _OutputIter __result) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); //这里直接采用复制操作,先把[middle,last)复制到result容器中, //再把[first,middle)内容复制到result容器中 return copy(__first, __middle, copy(__middle, __last, __result)); } // Return a random number in the range [0, __n). This function encapsulates // whether we're using rand (part of the standard C library) or lrand48 // (not standard, but a much better choice whenever it's available). template <class _Distance> inline _Distance __random_number(_Distance __n) { #ifdef __STL_NO_DRAND48 return rand() % __n; #else return lrand48() % __n; #endif } // random_shuffle //将区间[first,last)内的元素随机重排 //两个版本的不同是随机数的取得 //版本一是使用内部随机数产生器 //版本二是使用一个会产生随机数的仿函数 /* 函数功能:Rearranges the elements in the range [first,last) randomly. 函数原型: generator by default (1) template <class RandomAccessIterator> void random_shuffle (RandomAccessIterator first, RandomAccessIterator last); specific generator (2) template <class RandomAccessIterator, class RandomNumberGenerator> void random_shuffle (RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& gen); */ //版本一 template <class _RandomAccessIter> inline void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); if (__first == __last) return; for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) iter_swap(__i, __first + __random_number((__i - __first) + 1)); } //版本二 template <class _RandomAccessIter, class _RandomNumberGenerator> void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last, _RandomNumberGenerator& __rand) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); if (__first == __last) return; for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) iter_swap(__i, __first + __rand((__i - __first) + 1)); } // random_sample and random_sample_n (extensions, not part of the standard). template <class _ForwardIter, class _OutputIter, class _Distance> _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, _OutputIter __out, const _Distance __n) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); _Distance __remaining = 0; distance(__first, __last, __remaining); _Distance __m = min(__n, __remaining); while (__m > 0) { if (__random_number(__remaining) < __m) { *__out = *__first; ++__out; --__m; } --__remaining; ++__first; } return __out; } template <class _ForwardIter, class _OutputIter, class _Distance, class _RandomNumberGenerator> _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, _OutputIter __out, const _Distance __n, _RandomNumberGenerator& __rand) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_UNARY_FUNCTION_CHECK(_RandomNumberGenerator, _Distance, _Distance); _Distance __remaining = 0; distance(__first, __last, __remaining); _Distance __m = min(__n, __remaining); while (__m > 0) { if (__rand(__remaining) < __m) { *__out = *__first; ++__out; --__m; } --__remaining; ++__first; } return __out; } template <class _InputIter, class _RandomAccessIter, class _Distance> _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, _RandomAccessIter __out, const _Distance __n) { _Distance __m = 0; _Distance __t = __n; for ( ; __first != __last && __m < __n; ++__m, ++__first) __out[__m] = *__first; while (__first != __last) { ++__t; _Distance __M = __random_number(__t); if (__M < __n) __out[__M] = *__first; ++__first; } return __out + __m; } template <class _InputIter, class _RandomAccessIter, class _RandomNumberGenerator, class _Distance> _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, _RandomAccessIter __out, _RandomNumberGenerator& __rand, const _Distance __n) { __STL_UNARY_FUNCTION_CHECK(_RandomNumberGenerator, _Distance, _Distance); _Distance __m = 0; _Distance __t = __n; for ( ; __first != __last && __m < __n; ++__m, ++__first) __out[__m] = *__first; while (__first != __last) { ++__t; _Distance __M = __rand(__t); if (__M < __n) __out[__M] = *__first; ++__first; } return __out + __m; } template <class _InputIter, class _RandomAccessIter> inline _RandomAccessIter random_sample(_InputIter __first, _InputIter __last, _RandomAccessIter __out_first, _RandomAccessIter __out_last) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); return __random_sample(__first, __last, __out_first, __out_last - __out_first); } template <class _InputIter, class _RandomAccessIter, class _RandomNumberGenerator> inline _RandomAccessIter random_sample(_InputIter __first, _InputIter __last, _RandomAccessIter __out_first, _RandomAccessIter __out_last, _RandomNumberGenerator& __rand) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); return __random_sample(__first, __last, __out_first, __rand, __out_last - __out_first); } // partition, stable_partition, and their auxiliary functions //若迭代器的类型为forward_iterator_tag,则调用此函数 template <class _ForwardIter, class _Predicate> _ForwardIter __partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, forward_iterator_tag) { if (__first == __last) return __first;//若为空,直接退出 while (__pred(*__first))//若pred出first的值为true if (++__first == __last) return __first;//先移动迭代器first,在判断是否到达尾端last _ForwardIter __next = __first;//继续判断 while (++__next != __last)//若下一个位置依然不是尾端 if (__pred(*__next)) {//继续pred出next的值,若为true swap(*__first, *__next);//交换值 ++__first;//继续下一位置 } return __first; } //若迭代器的类型为bidirectional_iterator_tag,则调用此函数 template <class _BidirectionalIter, class _Predicate> _BidirectionalIter __partition(_BidirectionalIter __first, _BidirectionalIter __last, _Predicate __pred, bidirectional_iterator_tag) { while (true) { while (true) if (__first == __last)//若为空 return __first;//直接退出 else if (__pred(*__first))//first的值符合不移动条件,则不移动该值 ++__first;//只移动迭代器 else//若头指针符合移动 break;//跳出循环 --__last;//尾指针回溯 while (true) if (__first == __last)//头指针等于尾指针 return __first;//操作结束 else if (!__pred(*__last))//尾指针的元素符合不移动操作 --__last;//至移动迭代器,并不移动具体元素 else//尾指针的元素符合移动操作 break;//跳出循环 iter_swap(__first, __last);//头尾指针交换元素 ++__first;//准备下一次循环 } } //将区间[first,last)的元素进行排序,被pred判断为true的放在区间的前段,判定为false的放在区间后段 //该算算可能会使元素的元素位置放生改变. /* 算法功能:Rearranges the elements from the range [first,last), in such a way that all the elements for which pred returns true precede all those for which it returns false. The iterator returned points to the first element of the second group. 算法原型: template <class BidirectionalIterator, class UnaryPredicate> BidirectionalIterator partition (BidirectionalIterator first, BidirectionalIterator last, UnaryPredicate pred); */ template <class _ForwardIter, class _Predicate> inline _ForwardIter partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_ForwardIter>::value_type); //首先萃取出迭代器first的类型,根据迭代器的类型调用不同的函数 return __partition(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); } //partition函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::partition #include <vector> // std::vector bool IsOdd (int i) { return (i%2)==1; } int main () { std::vector<int> myvector; // set some values: for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9 std::vector<int>::iterator bound; bound = std::partition (myvector.begin(), myvector.end(), IsOdd); // print out content: std::cout << "odd elements:"; for (std::vector<int>::iterator it=myvector.begin(); it!=bound; ++it) std::cout << ' ' << *it; std::cout << '\n'; std::cout << "even elements:"; for (std::vector<int>::iterator it=bound; it!=myvector.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: odd elements: 1 9 3 7 5 even elements: 6 4 8 2 */ template <class _ForwardIter, class _Predicate, class _Distance> _ForwardIter __inplace_stable_partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, _Distance __len) { if (__len == 1) return __pred(*__first) ? __last : __first; _ForwardIter __middle = __first; advance(__middle, __len / 2); return rotate(__inplace_stable_partition(__first, __middle, __pred, __len / 2), __middle, __inplace_stable_partition(__middle, __last, __pred, __len - __len / 2)); } template <class _ForwardIter, class _Pointer, class _Predicate, class _Distance> _ForwardIter __stable_partition_adaptive(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, _Distance __len, _Pointer __buffer, _Distance __buffer_size) { if (__len <= __buffer_size) { _ForwardIter __result1 = __first; _Pointer __result2 = __buffer; for ( ; __first != __last ; ++__first) if (__pred(*__first)) { *__result1 = *__first; ++__result1; } else { *__result2 = *__first; ++__result2; } copy(__buffer, __result2, __result1); return __result1; } else { _ForwardIter __middle = __first; advance(__middle, __len / 2); return rotate(__stable_partition_adaptive( __first, __middle, __pred, __len / 2, __buffer, __buffer_size), __middle, __stable_partition_adaptive( __middle, __last, __pred, __len - __len / 2, __buffer, __buffer_size)); } } template <class _ForwardIter, class _Predicate, class _Tp, class _Distance> inline _ForwardIter __stable_partition_aux(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, _Tp*, _Distance*) { _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last); if (__buf.size() > 0) return __stable_partition_adaptive(__first, __last, __pred, _Distance(__buf.requested_size()), __buf.begin(), __buf.size()); else return __inplace_stable_partition(__first, __last, __pred, _Distance(__buf.requested_size())); } template <class _ForwardIter, class _Predicate> inline _ForwardIter stable_partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return __first; else return __stable_partition_aux(__first, __last, __pred, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } //找出快速排序的枢纽位置 //版本一采用operator< template <class _RandomAccessIter, class _Tp> _RandomAccessIter __unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last, _Tp __pivot) { //找出枢纽轴的位置 //令头端迭代器向尾端方向移动,尾端迭代器向头端移动。 //当*first不小于枢纽值时,就停下来,当*last不大于枢纽值时也停下来,然后检测两个迭代器是否交错 //如果first仍然在左侧而last仍然在右侧,就交换两个元素,然后各自调整位置,向中央逼近,再继续执行相同的行为. //直到first和last两个迭代器交错,此时表示已找到枢纽轴位置即first所在的位置 while (true) { while (*__first < __pivot) ++__first;//first向尾端移动,直到遇到不小于枢纽值时,停止 --__last; while (__pivot < *__last) --__last;//last向头端移动,直到遇到不大于枢纽值时,停止 if (!(__first < __last))//检测两个迭代器是否交错 return __first;//交错,则此时已找到,即为first迭代器所指位置 iter_swap(__first, __last);//否则交换迭代器所指的元素 ++__first;//继续执行相同行为 } } //版本一采用__comp template <class _RandomAccessIter, class _Tp, class _Compare> _RandomAccessIter __unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last, _Tp __pivot, _Compare __comp) { while (true) { while (__comp(*__first, __pivot)) ++__first; --__last; while (__comp(__pivot, *__last)) --__last; if (!(__first < __last)) return __first; iter_swap(__first, __last); ++__first; } } const int __stl_threshold = 16; // sort() and its auxiliary functions. //__insertion_sort版本一的辅助函数 template <class _RandomAccessIter, class _Tp> void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) { _RandomAccessIter __next = __last; --__next; //__insertion_sort的内循环 //注意:一旦不再出现逆转对,循环就结束 while (__val < *__next) {//存在逆转对 *__last = *__next;//调整元素 __last = __next;//调整迭代器 --__next;//左移一个位置 } *__last = __val;//value的正确插入位置 } //__insertion_sort版本二的辅助函数 template <class _RandomAccessIter, class _Tp, class _Compare> void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, _Compare __comp) { _RandomAccessIter __next = __last; --__next; while (__comp(__val, *__next)) { *__last = *__next; __last = __next; --__next; } *__last = __val; } //__insertion_sort版本一的辅助函数 template <class _RandomAccessIter, class _Tp> inline void __linear_insert(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*) { _Tp __val = *__last;//记录尾元素 if (__val < *__first) {//尾元素比头元素还小 //将整个区间向右移一个位置 copy_backward(__first, __last, __last + 1); *__first = __val;//令头元素等于原先的尾元素 //以上两行命令的功能相等于交换两个元素 } else//尾元素不小于头元素 __unguarded_linear_insert(__last, __val); } //__insertion_sort版本二的辅助函数 template <class _RandomAccessIter, class _Tp, class _Compare> inline void __linear_insert(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Compare __comp) { _Tp __val = *__last; if (__comp(__val, *__first)) { copy_backward(__first, __last, __last + 1); *__first = __val; } else __unguarded_linear_insert(__last, __val, __comp); } //__insertion_sort以双层循环形式进行。外循环遍历整个序列,每次迭代决定出一个子区间; //内循环遍历子区间,将子区间内的每一个“逆转对”倒转过来,如果一旦不存在“逆转对”,表示排序完毕。 //“逆转对”概念:指任何两个迭代器i和j,i<j,而*i>*j. //版本一 template <class _RandomAccessIter> void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { if (__first == __last) return; //若区间为空,则退出 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)//外循环,遍历整个区间 //[first,i)形成的子空间 __linear_insert(__first, __i, __VALUE_TYPE(__first)); } //版本二 template <class _RandomAccessIter, class _Compare> void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { if (__first == __last) return; for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) __linear_insert(__first, __i, __VALUE_TYPE(__first), __comp); } template <class _RandomAccessIter, class _Tp> void __unguarded_insertion_sort_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*) { for (_RandomAccessIter __i = __first; __i != __last; ++__i) __unguarded_linear_insert(__i, _Tp(*__i)); } //sort版本一的辅助函数 template <class _RandomAccessIter> inline void __unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first)); } template <class _RandomAccessIter, class _Tp, class _Compare> void __unguarded_insertion_sort_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Compare __comp) { for (_RandomAccessIter __i = __first; __i != __last; ++__i) __unguarded_linear_insert(__i, _Tp(*__i), __comp); } template <class _RandomAccessIter, class _Compare> inline void __unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first), __comp); } //sort版本一的辅助函数 template <class _RandomAccessIter> void __final_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { if (__last - __first > __stl_threshold) {//判断元素个数是否大于16 //则把区间分割成两段,一端长度为16,另一端为剩余的长度 __insertion_sort(__first, __first + __stl_threshold); __unguarded_insertion_sort(__first + __stl_threshold, __last); } else//若不大于16,直接调用插入排序 __insertion_sort(__first, __last); } template <class _RandomAccessIter, class _Compare> void __final_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { if (__last - __first > __stl_threshold) { __insertion_sort(__first, __first + __stl_threshold, __comp); __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp); } else __insertion_sort(__first, __last, __comp); } //_lg()函数是用来控制分割恶化的情况 //该函数找出2^k <= n 的最大值k; //例如:n=7,得k=2; n=20,得k=4; n=8,得k=3; template <class _Size> inline _Size __lg(_Size __n) { _Size __k; for (__k = 0; __n != 1; __n >>= 1) ++__k; return __k; } //sort版本一的辅助函数 //参数__depth_limit表示最大的分割层数 template <class _RandomAccessIter, class _Tp, class _Size> void __introsort_loop(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Size __depth_limit) { //__stl_threshold为全局常量,其值为16 while (__last - __first > __stl_threshold) {//若区间长度大于16 if (__depth_limit == 0) {//表示分割恶化 partial_sort(__first, __last, __last);//转而调用堆排序heap_sort() return; } --__depth_limit; //计算分割点cut,枢纽值是采用首、尾、中央三个的中间值 _RandomAccessIter __cut = __unguarded_partition(__first, __last, _Tp(__median(*__first, *(__first + (__last - __first)/2), *(__last - 1)))); //对右半部分递归地进行排序 __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit); __last = __cut;//接下来对左半部分递归地进行排序 } } template <class _RandomAccessIter, class _Tp, class _Size, class _Compare> void __introsort_loop(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Size __depth_limit, _Compare __comp) { while (__last - __first > __stl_threshold) { if (__depth_limit == 0) { partial_sort(__first, __last, __last, __comp); return; } --__depth_limit; _RandomAccessIter __cut = __unguarded_partition(__first, __last, _Tp(__median(*__first, *(__first + (__last - __first)/2), *(__last - 1), __comp)), __comp); __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp); __last = __cut; } } //SGI STL的排序算法,迭代器参数的类型必须是随机访问迭代器_RandomAccessIter /* 函数功能:Sorts the elements in the range [first,last) into ascending order. 函数原型: default (1) :版本一采用默认的operator< template <class RandomAccessIterator> void sort (RandomAccessIterator first, RandomAccessIterator last); custom (2) :版本二采用仿函数comp template <class RandomAccessIterator, class Compare> void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp); */ //版本一 template <class _RandomAccessIter> inline void sort(_RandomAccessIter __first, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); //_lg()函数是用来控制分割恶化的情况 if (__first != __last) { __introsort_loop(__first, __last, __VALUE_TYPE(__first), __lg(__last - __first) * 2); //进行插入排序 __final_insertion_sort(__first, __last); } } //版本二 template <class _RandomAccessIter, class _Compare> inline void sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); if (__first != __last) { __introsort_loop(__first, __last, __VALUE_TYPE(__first), __lg(__last - __first) * 2, __comp); __final_insertion_sort(__first, __last, __comp); } } // stable_sort() and its auxiliary functions. template <class _RandomAccessIter> void __inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last) { if (__last - __first < 15) { __insertion_sort(__first, __last); return; } _RandomAccessIter __middle = __first + (__last - __first) / 2; __inplace_stable_sort(__first, __middle); __inplace_stable_sort(__middle, __last); __merge_without_buffer(__first, __middle, __last, __middle - __first, __last - __middle); } template <class _RandomAccessIter, class _Compare> void __inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { if (__last - __first < 15) { __insertion_sort(__first, __last, __comp); return; } _RandomAccessIter __middle = __first + (__last - __first) / 2; __inplace_stable_sort(__first, __middle, __comp); __inplace_stable_sort(__middle, __last, __comp); __merge_without_buffer(__first, __middle, __last, __middle - __first, __last - __middle, __comp); } template <class _RandomAccessIter1, class _RandomAccessIter2, class _Distance> void __merge_sort_loop(_RandomAccessIter1 __first, _RandomAccessIter1 __last, _RandomAccessIter2 __result, _Distance __step_size) { _Distance __two_step = 2 * __step_size; while (__last - __first >= __two_step) { __result = merge(__first, __first + __step_size, __first + __step_size, __first + __two_step, __result); __first += __two_step; } __step_size = min(_Distance(__last - __first), __step_size); merge(__first, __first + __step_size, __first + __step_size, __last, __result); } template <class _RandomAccessIter1, class _RandomAccessIter2, class _Distance, class _Compare> void __merge_sort_loop(_RandomAccessIter1 __first, _RandomAccessIter1 __last, _RandomAccessIter2 __result, _Distance __step_size, _Compare __comp) { _Distance __two_step = 2 * __step_size; while (__last - __first >= __two_step) { __result = merge(__first, __first + __step_size, __first + __step_size, __first + __two_step, __result, __comp); __first += __two_step; } __step_size = min(_Distance(__last - __first), __step_size); merge(__first, __first + __step_size, __first + __step_size, __last, __result, __comp); } const int __stl_chunk_size = 7; template <class _RandomAccessIter, class _Distance> void __chunk_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Distance __chunk_size) { while (__last - __first >= __chunk_size) { __insertion_sort(__first, __first + __chunk_size); __first += __chunk_size; } __insertion_sort(__first, __last); } template <class _RandomAccessIter, class _Distance, class _Compare> void __chunk_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Distance __chunk_size, _Compare __comp) { while (__last - __first >= __chunk_size) { __insertion_sort(__first, __first + __chunk_size, __comp); __first += __chunk_size; } __insertion_sort(__first, __last, __comp); } template <class _RandomAccessIter, class _Pointer, class _Distance> void __merge_sort_with_buffer(_RandomAccessIter __first, _RandomAccessIter __last, _Pointer __buffer, _Distance*) { _Distance __len = __last - __first; _Pointer __buffer_last = __buffer + __len; _Distance __step_size = __stl_chunk_size; __chunk_insertion_sort(__first, __last, __step_size); while (__step_size < __len) { __merge_sort_loop(__first, __last, __buffer, __step_size); __step_size *= 2; __merge_sort_loop(__buffer, __buffer_last, __first, __step_size); __step_size *= 2; } } template <class _RandomAccessIter, class _Pointer, class _Distance, class _Compare> void __merge_sort_with_buffer(_RandomAccessIter __first, _RandomAccessIter __last, _Pointer __buffer, _Distance*, _Compare __comp) { _Distance __len = __last - __first; _Pointer __buffer_last = __buffer + __len; _Distance __step_size = __stl_chunk_size; __chunk_insertion_sort(__first, __last, __step_size, __comp); while (__step_size < __len) { __merge_sort_loop(__first, __last, __buffer, __step_size, __comp); __step_size *= 2; __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp); __step_size *= 2; } } template <class _RandomAccessIter, class _Pointer, class _Distance> void __stable_sort_adaptive(_RandomAccessIter __first, _RandomAccessIter __last, _Pointer __buffer, _Distance __buffer_size) { _Distance __len = (__last - __first + 1) / 2; _RandomAccessIter __middle = __first + __len; if (__len > __buffer_size) { __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size); __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size); } else { __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0); __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0); } __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), _Distance(__last - __middle), __buffer, __buffer_size); } template <class _RandomAccessIter, class _Pointer, class _Distance, class _Compare> void __stable_sort_adaptive(_RandomAccessIter __first, _RandomAccessIter __last, _Pointer __buffer, _Distance __buffer_size, _Compare __comp) { _Distance __len = (__last - __first + 1) / 2; _RandomAccessIter __middle = __first + __len; if (__len > __buffer_size) { __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size, __comp); __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size, __comp); } else { __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0, __comp); __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0, __comp); } __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), _Distance(__last - __middle), __buffer, __buffer_size, __comp); } template <class _RandomAccessIter, class _Tp, class _Distance> inline void __stable_sort_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Distance*) { _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); if (buf.begin() == 0) __inplace_stable_sort(__first, __last); else __stable_sort_adaptive(__first, __last, buf.begin(), _Distance(buf.size())); } template <class _RandomAccessIter, class _Tp, class _Distance, class _Compare> inline void __stable_sort_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Distance*, _Compare __comp) { _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); if (buf.begin() == 0) __inplace_stable_sort(__first, __last, __comp); else __stable_sort_adaptive(__first, __last, buf.begin(), _Distance(buf.size()), __comp); } template <class _RandomAccessIter> inline void stable_sort(_RandomAccessIter __first, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); __stable_sort_aux(__first, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } template <class _RandomAccessIter, class _Compare> inline void stable_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __stable_sort_aux(__first, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first), __comp); } // partial_sort, partial_sort_copy, and auxiliary functions. //重新安排序列[first,last),使序列前半部分middle-first个最小元素以递增顺序排序,并将其置于[first,middle) //其余last-middle个元素不指定任何排序,并将其置于[middle,last) //注意:迭代器middle是在[first,last)范围之内 /* 函数功能:Rearranges the elements in the range [first,last), in such a way that the elements before middle are the smallest elements in the entire range and are sorted in ascending order, while the remaining elements are left without any specific order. 函数原型: default (1) 版本一 operator< template <class RandomAccessIterator> void partial_sort (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last); custom (2) 版本二 comp template <class RandomAccessIterator, class Compare> void partial_sort (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); */ template <class _RandomAccessIter, class _Tp> void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, _Tp*) { //利用heap的知识,在SGI STL中,是采用最大堆 //将[first,middle)区间的元素创建成最大堆 //再根据最大堆的性质,一个一个弹出堆,并将其保存,即堆排序 make_heap(__first, __middle);//创建最大堆,定义与<stl_heap.h>文件 //以下是在区间中[first,last)找出middle-first个最小元素 //这里的是将后半部分[middle,last)的元素依次与最大堆的根节点元素(即堆的最大元素)比较 //若小于堆的最大元素,则与堆的最大元素交换,并调整堆,使其依次成为最大堆 //若不小于堆的最大元素,则不作任何操作 for (_RandomAccessIter __i = __middle; __i < __last; ++__i) if (*__i < *__first) __pop_heap(__first, __middle, __i, _Tp(*__i), __DISTANCE_TYPE(__first)); sort_heap(__first, __middle);//对最大堆进行堆排序 } //版本一 template <class _RandomAccessIter> inline void partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first)); } template <class _RandomAccessIter, class _Tp, class _Compare> void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, _Tp*, _Compare __comp) { make_heap(__first, __middle, __comp); for (_RandomAccessIter __i = __middle; __i < __last; ++__i) if (__comp(*__i, *__first)) __pop_heap(__first, __middle, __i, _Tp(*__i), __comp, __DISTANCE_TYPE(__first)); sort_heap(__first, __middle, __comp); } //版本二 template <class _RandomAccessIter, class _Compare> inline void partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first), __comp); } //partial_sort_copy与partial_sort的实现机制是相同,只是partial_sort_copy将元素排序后放在以result起始的容器中 template <class _InputIter, class _RandomAccessIter, class _Distance, class _Tp> _RandomAccessIter __partial_sort_copy(_InputIter __first, _InputIter __last, _RandomAccessIter __result_first, _RandomAccessIter __result_last, _Distance*, _Tp*) { if (__result_first == __result_last) return __result_last; _RandomAccessIter __result_real_last = __result_first; while(__first != __last && __result_real_last != __result_last) { *__result_real_last = *__first; ++__result_real_last; ++__first; } make_heap(__result_first, __result_real_last); while (__first != __last) { if (*__first < *__result_first) __adjust_heap(__result_first, _Distance(0), _Distance(__result_real_last - __result_first), _Tp(*__first)); ++__first; } sort_heap(__result_first, __result_real_last); return __result_real_last; } template <class _InputIter, class _RandomAccessIter> inline _RandomAccessIter partial_sort_copy(_InputIter __first, _InputIter __last, _RandomAccessIter __result_first, _RandomAccessIter __result_last) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_CONVERTIBLE(typename iterator_traits<_InputIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, _LessThanComparable); return __partial_sort_copy(__first, __last, __result_first, __result_last, __DISTANCE_TYPE(__result_first), __VALUE_TYPE(__first)); } template <class _InputIter, class _RandomAccessIter, class _Compare, class _Distance, class _Tp> _RandomAccessIter __partial_sort_copy(_InputIter __first, _InputIter __last, _RandomAccessIter __result_first, _RandomAccessIter __result_last, _Compare __comp, _Distance*, _Tp*) { if (__result_first == __result_last) return __result_last; _RandomAccessIter __result_real_last = __result_first; while(__first != __last && __result_real_last != __result_last) { *__result_real_last = *__first; ++__result_real_last; ++__first; } make_heap(__result_first, __result_real_last, __comp); while (__first != __last) { if (__comp(*__first, *__result_first)) __adjust_heap(__result_first, _Distance(0), _Distance(__result_real_last - __result_first), _Tp(*__first), __comp); ++__first; } sort_heap(__result_first, __result_real_last, __comp); return __result_real_last; } template <class _InputIter, class _RandomAccessIter, class _Compare> inline _RandomAccessIter partial_sort_copy(_InputIter __first, _InputIter __last, _RandomAccessIter __result_first, _RandomAccessIter __result_last, _Compare __comp) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_CONVERTIBLE(typename iterator_traits<_InputIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); return __partial_sort_copy(__first, __last, __result_first, __result_last, __comp, __DISTANCE_TYPE(__result_first), __VALUE_TYPE(__first)); } // nth_element() and its auxiliary functions. //nth_element版本一辅助函数 template <class _RandomAccessIter, class _Tp> void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last, _Tp*) { while (__last - __first > 3) {//区间长度大于3 //获取分割点cut _RandomAccessIter __cut = __unguarded_partition(__first, __last, _Tp(__median(*__first, *(__first + (__last - __first)/2), *(__last - 1)))); if (__cut <= __nth)//若分割点小于指定位置,则nth位置在右半段 __first = __cut;//再对右半段进行分割 else //否则,对左半段进行分割 __last = __cut; } __insertion_sort(__first, __last); } //重新排序序列[first,last),使迭代器nth所指的元素,与“整个[first,last)序列完整排序后,同一位置的元素”同值. //此外,必须保证[nth,last)内的所有元素不小于[first,nth)内的元素,但是对于序列[first,nth)和序列[nth,last)内的元素的排序顺序不能确定. /* 函数功能:Rearranges the elements in the range [first,last), in such a way that the element at the nth position is the element that would be in that position in a sorted sequence. 函数原型: default (1) template <class RandomAccessIterator> void nth_element (RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last); custom (2) template <class RandomAccessIterator, class Compare> void nth_element (RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); */ //nth_element版本一 template <class _RandomAccessIter> inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); __nth_element(__first, __nth, __last, __VALUE_TYPE(__first)); } template <class _RandomAccessIter, class _Tp, class _Compare> void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last, _Tp*, _Compare __comp) { while (__last - __first > 3) { _RandomAccessIter __cut = __unguarded_partition(__first, __last, _Tp(__median(*__first, *(__first + (__last - __first)/2), *(__last - 1), __comp)), __comp); if (__cut <= __nth) __first = __cut; else __last = __cut; } __insertion_sort(__first, __last, __comp); } template <class _RandomAccessIter, class _Compare> inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __nth_element(__first, __nth, __last, __VALUE_TYPE(__first), __comp); } // Binary search (lower_bound, upper_bound, equal_range, binary_search). template <class _ForwardIter, class _Tp, class _Distance> _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Distance*) { _Distance __len = 0; distance(__first, __last, __len);//求取整个区间的长度len _Distance __half; _ForwardIter __middle;//定义区间的中间迭代器 while (__len > 0) {//若区间不为空,则在区间[first,last)开始查找value值 __half = __len >> 1;//向右移一位,相当于除以2,即取区间的中间值 __middle = __first;//middle初始化为区间的起始位置 advance(__middle, __half);//middle向后移half位,此时middle为区间的中间值 if (*__middle < __val) {//将value值与中间值比较,即是二分查找,若中间值小于value,则继续查找右半部分 //下面两行令first指向middle的下一个位置 __first = __middle; ++__first; __len = __len - __half - 1;//调整查找区间的长度 } else __len = __half;//否则查找左半部分 } return __first; } //在已排序区间[first,last)查找value值 //若该区间存在与value相等的元素,则返回指向第一个与value相等的迭代器 //若该区间不存在与value相等的元素,则返回指向第一个不小于value值的迭代器 //若该区间的任何元素都比value值小,则返回last /* 函数功能:Returns an iterator pointing to the first element in the range [first,last) which does not compare less than val. 函数原型: default (1) :版本一采用operator<比较 template <class ForwardIterator, class T> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val); custom (2) :版本二采用仿函数comp比较规则 template <class ForwardIterator, class T, class Compare> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); */ //版本一 template <class _ForwardIter, class _Tp> inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_REQUIRES(_Tp, _LessThanComparable); return __lower_bound(__first, __last, __val, __DISTANCE_TYPE(__first)); } template <class _ForwardIter, class _Tp, class _Compare, class _Distance> _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp, _Distance*) { _Distance __len = 0; distance(__first, __last, __len);//求取整个区间的长度len _Distance __half; _ForwardIter __middle;//定义区间的中间迭代器 while (__len > 0) {//若区间不为空,则在区间[first,last)开始查找value值 __half = __len >> 1;//向右移一位,相当于除以2,即取区间的中间值 __middle = __first;//middle初始化为区间的起始位置 advance(__middle, __half);//middle向后移half位,此时middle为区间的中间值 if (__comp(*__middle, __val)) {//若comp判断为true,则继续在右半部分查找 //下面两行令first指向middle的下一个位置 __first = __middle; ++__first; __len = __len - __half - 1;//调整查找区间的长度 } else __len = __half;//否则查找左半部分 } return __first; } //版本二: template <class _ForwardIter, class _Tp, class _Compare> inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); return __lower_bound(__first, __last, __val, __comp, __DISTANCE_TYPE(__first)); } template <class _ForwardIter, class _Tp, class _Distance> _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Distance*) { _Distance __len = 0; distance(__first, __last, __len);//求取整个区间的长度len _Distance __half; _ForwardIter __middle;//定义区间的中间迭代器 while (__len > 0) {//若区间不为空,则在区间[first,last)开始查找value值 __half = __len >> 1;//向右移一位,相当于除以2,即取区间的中间值 __middle = __first;//middle初始化为区间的起始位置 advance(__middle, __half);//middle向后移half位,此时middle为区间的中间值 if (__val < *__middle)//若value小于中间元素值 __len = __half;//查找左半部分 else { //下面两行令first指向middle的下一个位置 __first = __middle; ++__first; __len = __len - __half - 1;//更新len的值 } } return __first; } //在已排序区间[first,last)查找value值 //返回大于value值的第一个元素的迭代器 /* 函数功能:Returns an iterator pointing to the first element in the range [first,last) which compares greater than val. 函数原型: default (1) :版本一采用operator<比较 template <class ForwardIterator, class T> ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val); custom (2) :版本二采用仿函数comp比较规则 template <class ForwardIterator, class T, class Compare> ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); */ //版本一 template <class _ForwardIter, class _Tp> inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_REQUIRES(_Tp, _LessThanComparable); return __upper_bound(__first, __last, __val, __DISTANCE_TYPE(__first)); } template <class _ForwardIter, class _Tp, class _Compare, class _Distance> _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp, _Distance*) { _Distance __len = 0; distance(__first, __last, __len); _Distance __half; _ForwardIter __middle; while (__len > 0) { __half = __len >> 1; __middle = __first; advance(__middle, __half); if (__comp(__val, *__middle)) __len = __half; else { __first = __middle; ++__first; __len = __len - __half - 1; } } return __first; } //版本二 template <class _ForwardIter, class _Tp, class _Compare> inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); return __upper_bound(__first, __last, __val, __comp, __DISTANCE_TYPE(__first)); } //函数举例 /* #include <iostream> // std::cout #include <algorithm> // std::lower_bound, std::upper_bound, std::sort #include <vector> // std::vector int main () { int myints[] = {10,20,30,30,20,10,10,20}; std::vector<int> v(myints,myints+8); // 10 20 30 30 20 10 10 20 std::sort (v.begin(), v.end()); // 10 10 10 20 20 20 30 30 std::vector<int>::iterator low,up; low=std::lower_bound (v.begin(), v.end(), 20); // ^ up= std::upper_bound (v.begin(), v.end(), 20); // ^ std::cout << "lower_bound at position " << (low- v.begin()) << '\n'; std::cout << "upper_bound at position " << (up - v.begin()) << '\n'; return 0; } Output: lower_bound at position 3 upper_bound at position 6 */ template <class _ForwardIter, class _Tp, class _Distance> pair<_ForwardIter, _ForwardIter> __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Distance*) { _Distance __len = 0; distance(__first, __last, __len);//计算区间的长度len _Distance __half; _ForwardIter __middle, __left, __right; while (__len > 0) {//若区间非空 __half = __len >> 1;//len右移一位,相等于除以2,即half为区间的长度的一半 __middle = __first;//初始化middle的值 advance(__middle, __half);//前进middle位置,使其指向区间中间位置 if (*__middle < __val) {//若指定元素value大于中间元素值,则在右半部分继续查找 //下面两行使first指向middle的下一个位置,即右半区间的起始位置 __first = __middle; ++__first; __len = __len - __half - 1;//更新待查找区间的长度 } else if (__val < *__middle)//若指定元素value小于中间元素值,则在左半部分继续查找 __len = __half;//更新待查找区间的长度 else {//若指定元素value等于中间元素值 //在前半部分找lower_bound位置 __left = lower_bound(__first, __middle, __val); advance(__first, __len); //在后半部分找upper_bound __right = upper_bound(++__middle, __first, __val); return pair<_ForwardIter, _ForwardIter>(__left, __right);//返回pair对象,第一个迭代器为left,第二个迭代器为right } } return pair<_ForwardIter, _ForwardIter>(__first, __first); } //查找区间与value相等的相邻重复元素的起始位置和结束位置 //注意:[first,last)是已排序,思想还是采用二分查找法 //同样也有两个版本 /* 函数功能:Returns the bounds of the subrange that includes all the elements of the range [first,last) with values equivalent to val. 函数原型: default (1) :版本一默认operator< template <class ForwardIterator, class T> pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const T& val); custom (2) :版本二采用仿函数comp template <class ForwardIterator, class T, class Compare> pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); */ //版本一 template <class _ForwardIter, class _Tp> inline pair<_ForwardIter, _ForwardIter> equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_REQUIRES(_Tp, _LessThanComparable); return __equal_range(__first, __last, __val, __DISTANCE_TYPE(__first)); } template <class _ForwardIter, class _Tp, class _Compare, class _Distance> pair<_ForwardIter, _ForwardIter> __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp, _Distance*) { _Distance __len = 0; distance(__first, __last, __len); _Distance __half; _ForwardIter __middle, __left, __right; while (__len > 0) { __half = __len >> 1; __middle = __first; advance(__middle, __half); if (__comp(*__middle, __val)) { __first = __middle; ++__first; __len = __len - __half - 1; } else if (__comp(__val, *__middle)) __len = __half; else { __left = lower_bound(__first, __middle, __val, __comp); advance(__first, __len); __right = upper_bound(++__middle, __first, __val, __comp); return pair<_ForwardIter, _ForwardIter>(__left, __right); } } return pair<_ForwardIter, _ForwardIter>(__first, __first); } //版本二 template <class _ForwardIter, class _Tp, class _Compare> inline pair<_ForwardIter, _ForwardIter> equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); return __equal_range(__first, __last, __val, __comp, __DISTANCE_TYPE(__first)); } //equal_range函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::equal_range, std::sort #include <vector> // std::vector bool mygreater (int i,int j) { return (i>j); } int main () { int myints[] = {10,20,30,30,20,10,10,20}; std::vector<int> v(myints,myints+8); // 10 20 30 30 20 10 10 20 std::pair<std::vector<int>::iterator,std::vector<int>::iterator> bounds; // using default comparison: std::sort (v.begin(), v.end()); // 10 10 10 20 20 20 30 30 bounds=std::equal_range (v.begin(), v.end(), 20); // ^ ^ std::cout << "bounds at positions " << (bounds.first - v.begin()); std::cout << " and " << (bounds.second - v.begin()) << '\n'; // using "mygreater" as comp: std::sort (v.begin(), v.end(), mygreater); // 30 30 20 20 20 10 10 10 bounds=std::equal_range (v.begin(), v.end(), 20, mygreater); // ^ ^ std::cout << "bounds at positions " << (bounds.first - v.begin()); std::cout << " and " << (bounds.second - v.begin()) << '\n'; return 0; } Output: bounds at positions 3 and 6 bounds at positions 2 and 5 */ //二分查找法 //注意:[first,last)是已排序 //同样也有两个版本 /* 函数功能:Returns true if any element in the range [first,last) is equivalent to val, and false otherwise. 函数原型: default (1) :版本一默认operator< template <class ForwardIterator, class T> bool binary_search (ForwardIterator first, ForwardIterator last, const T& val); custom (2) :版本二采用仿函数comp template <class ForwardIterator, class T, class Compare> bool binary_search (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); */ template <class _ForwardIter, class _Tp> bool binary_search(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_REQUIRES(_Tp, _LessThanComparable); _ForwardIter __i = lower_bound(__first, __last, __val);//调用二分查找函数,并返回不小于value值的第一个迭代器位置i return __i != __last && !(__val < *__i); } template <class _ForwardIter, class _Tp, class _Compare> bool binary_search(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); _ForwardIter __i = lower_bound(__first, __last, __val, __comp);//调用二分查找函数,并返回不小于value值的第一个迭代器位置i return __i != __last && !__comp(__val, *__i); } // merge, with and without an explicitly supplied comparison function. //将两个已排序的区间[first1,last1)和区间[first2,last2)合并 /* 函数功能:Combines the elements in the sorted ranges [first1,last1) and [first2,last2), into a new range beginning at result with all its elements sorted. 函数原型: default (1) :版本一 template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); custom (2) :版本二 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); */ //版本一: template <class _InputIter1, class _InputIter2, class _OutputIter> _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); //两个序列都尚未到达尾端,则执行while循环 /* 情况1:若序列二元素较小,则记录到目标区,且移动序列二的迭代器,但是序列一的迭代器不变. 情况2:若序列一元素较小或相等,则记录到目标区,且移动序列一的迭代器,但是序列二的迭代器不变. 最后:把剩余元素的序列复制到目标区 */ while (__first1 != __last1 && __first2 != __last2) { //情况1 if (*__first2 < *__first1) {//若序列二元素较小 *__result = *__first2;//将元素记录到目标区 ++__first2;//移动迭代器 } //情况2 else {//若序列一元素较小或相等 *__result = *__first1;//将元素记录到目标区 ++__first1;//移动迭代器 } ++__result;//更新目标区位置,以便下次记录数据 } //若有序列到达尾端,则把没到达尾端的序列剩余元素复制到目标区 //此时,区间[first1,last1)和区间[first2,last2)至少一个必定为空 return copy(__first2, __last2, copy(__first1, __last1, __result)); } //版本二 template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare> _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter1>::value_type); while (__first1 != __last1 && __first2 != __last2) { if (__comp(*__first2, *__first1)) { *__result = *__first2; ++__first2; } else { *__result = *__first1; ++__first1; } ++__result; } return copy(__first2, __last2, copy(__first1, __last1, __result)); } //merge函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::merge, std::sort #include <vector> // std::vector int main () { int first[] = {5,10,15,20,25}; int second[] = {50,40,30,20,10}; std::vector<int> v(10); std::sort (first,first+5); std::sort (second,second+5); std::merge (first,first+5,second,second+5,v.begin()); std::cout << "The resulting vector contains:"; for (std::vector<int>::iterator it=v.begin(); it!=v.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: The resulting vector contains: 5 10 10 15 20 20 25 30 40 50 */ // inplace_merge and its auxiliary functions. //版本一的辅助函数,无缓冲区的操作 template <class _BidirectionalIter, class _Distance> void __merge_without_buffer(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance __len1, _Distance __len2) { if (__len1 == 0 || __len2 == 0) return; if (__len1 + __len2 == 2) { if (*__middle < *__first) iter_swap(__first, __middle); return; } _BidirectionalIter __first_cut = __first; _BidirectionalIter __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) { __len11 = __len1 / 2; advance(__first_cut, __len11); __second_cut = lower_bound(__middle, __last, *__first_cut); distance(__middle, __second_cut, __len22); } else { __len22 = __len2 / 2; advance(__second_cut, __len22); __first_cut = upper_bound(__first, __middle, *__second_cut); distance(__first, __first_cut, __len11); } _BidirectionalIter __new_middle = rotate(__first_cut, __middle, __second_cut); __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22); __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22); } template <class _BidirectionalIter, class _Distance, class _Compare> void __merge_without_buffer(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance __len1, _Distance __len2, _Compare __comp) { if (__len1 == 0 || __len2 == 0) return; if (__len1 + __len2 == 2) { if (__comp(*__middle, *__first)) iter_swap(__first, __middle); return; } _BidirectionalIter __first_cut = __first; _BidirectionalIter __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) { __len11 = __len1 / 2; advance(__first_cut, __len11); __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); distance(__middle, __second_cut, __len22); } else { __len22 = __len2 / 2; advance(__second_cut, __len22); __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); distance(__first, __first_cut, __len11); } _BidirectionalIter __new_middle = rotate(__first_cut, __middle, __second_cut); __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22, __comp); __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22, __comp); } //版本一的辅助函数,有缓冲区的操作 template <class _BidirectionalIter1, class _BidirectionalIter2, class _Distance> _BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first, _BidirectionalIter1 __middle, _BidirectionalIter1 __last, _Distance __len1, _Distance __len2, _BidirectionalIter2 __buffer, _Distance __buffer_size) { _BidirectionalIter2 __buffer_end; if (__len1 > __len2 && __len2 <= __buffer_size) {//缓冲区足够放置序列二 __buffer_end = copy(__middle, __last, __buffer); copy_backward(__first, __middle, __last); return copy(__buffer, __buffer_end, __first); } else if (__len1 <= __buffer_size) {//缓冲区足够放置序列一 __buffer_end = copy(__first, __middle, __buffer); copy(__middle, __last, __first); return copy_backward(__buffer, __buffer_end, __last); } else//若缓冲区仍然不够,则调用STL算法rotate,不使用缓冲区 return rotate(__first, __middle, __last); } template <class _BidirectionalIter1, class _BidirectionalIter2, class _BidirectionalIter3> _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, _BidirectionalIter3 __result) { if (__first1 == __last1) return copy_backward(__first2, __last2, __result); if (__first2 == __last2) return copy_backward(__first1, __last1, __result); --__last1; --__last2; while (true) { if (*__last2 < *__last1) { *--__result = *__last1; if (__first1 == __last1) return copy_backward(__first2, ++__last2, __result); --__last1; } else { *--__result = *__last2; if (__first2 == __last2) return copy_backward(__first1, ++__last1, __result); --__last2; } } } template <class _BidirectionalIter1, class _BidirectionalIter2, class _BidirectionalIter3, class _Compare> _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, _BidirectionalIter3 __result, _Compare __comp) { if (__first1 == __last1) return copy_backward(__first2, __last2, __result); if (__first2 == __last2) return copy_backward(__first1, __last1, __result); --__last1; --__last2; while (true) { if (__comp(*__last2, *__last1)) { *--__result = *__last1; if (__first1 == __last1) return copy_backward(__first2, ++__last2, __result); --__last1; } else { *--__result = *__last2; if (__first2 == __last2) return copy_backward(__first1, ++__last1, __result); --__last2; } } } //版本一的辅助函数,有缓冲区的操作 template <class _BidirectionalIter, class _Distance, class _Pointer> void __merge_adaptive(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance __len1, _Distance __len2, _Pointer __buffer, _Distance __buffer_size) { if (__len1 <= __len2 && __len1 <= __buffer_size) { //case1:把序列一放在缓冲区 _Pointer __buffer_end = copy(__first, __middle, __buffer); //直接调用归并函数merge merge(__buffer, __buffer_end, __middle, __last, __first); } else if (__len2 <= __buffer_size) { //case2:把序列二放在缓冲区 _Pointer __buffer_end = copy(__middle, __last, __buffer); __merge_backward(__first, __middle, __buffer, __buffer_end, __last); } else {//case3:缓冲区不足放置任何一个序列 _BidirectionalIter __first_cut = __first; _BidirectionalIter __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) {//若序列一比较长 __len11 = __len1 / 2;//计算序列一的一半 advance(__first_cut, __len11);//让first_cut指向序列一的中间位置 //找出*__first_cut在[middle,last)区间中的第一个不小于*__first_cut的元素位置 __second_cut = lower_bound(__middle, __last, *__first_cut); //计算middle到__second_cut之间的距离,保存在__len22 distance(__middle, __second_cut, __len22); } else {//若序列二比较长 __len22 = __len2 / 2;//计算序列二的一半 advance(__second_cut, __len22);//让__second_cut指向序列二的中间位置 //找出*__second_cut在[first,middle)区间中的第一个大于*__second_cut的元素位置 __first_cut = upper_bound(__first, __middle, *__second_cut); //计算__first到__first_cut之间的距离,保存在__len11 distance(__first, __first_cut, __len11); } _BidirectionalIter __new_middle = __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, __len22, __buffer, __buffer_size); //对左半段递归调用 __merge_adaptive(__first, __first_cut, __new_middle, __len11, __len22, __buffer, __buffer_size); //对右半段递归调用 __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22, __buffer, __buffer_size); } } template <class _BidirectionalIter, class _Distance, class _Pointer, class _Compare> void __merge_adaptive(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance __len1, _Distance __len2, _Pointer __buffer, _Distance __buffer_size, _Compare __comp) { if (__len1 <= __len2 && __len1 <= __buffer_size) { _Pointer __buffer_end = copy(__first, __middle, __buffer); merge(__buffer, __buffer_end, __middle, __last, __first, __comp); } else if (__len2 <= __buffer_size) { _Pointer __buffer_end = copy(__middle, __last, __buffer); __merge_backward(__first, __middle, __buffer, __buffer_end, __last, __comp); } else { _BidirectionalIter __first_cut = __first; _BidirectionalIter __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) { __len11 = __len1 / 2; advance(__first_cut, __len11); __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); distance(__middle, __second_cut, __len22); } else { __len22 = __len2 / 2; advance(__second_cut, __len22); __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); distance(__first, __first_cut, __len11); } _BidirectionalIter __new_middle = __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, __len22, __buffer, __buffer_size); __merge_adaptive(__first, __first_cut, __new_middle, __len11, __len22, __buffer, __buffer_size, __comp); __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22, __buffer, __buffer_size, __comp); } } //版本一的辅助函数 template <class _BidirectionalIter, class _Tp, class _Distance> inline void __inplace_merge_aux(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Tp*, _Distance*) { _Distance __len1 = 0; distance(__first, __middle, __len1);//计算序列一的长度 _Distance __len2 = 0; distance(__middle, __last, __len2);//计算序列二的长度 //使用暂时缓冲区 _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); if (__buf.begin() == 0)//若缓冲区配置失败 //则调用不使用缓冲区的合并操作 __merge_without_buffer(__first, __middle, __last, __len1, __len2); else//若分配成功 //则调用具有缓冲区的合并操作 __merge_adaptive(__first, __middle, __last, __len1, __len2, __buf.begin(), _Distance(__buf.size())); } template <class _BidirectionalIter, class _Tp, class _Distance, class _Compare> inline void __inplace_merge_aux(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Tp*, _Distance*, _Compare __comp) { _Distance __len1 = 0; distance(__first, __middle, __len1); _Distance __len2 = 0; distance(__middle, __last, __len2); _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); if (__buf.begin() == 0) __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp); else __merge_adaptive(__first, __middle, __last, __len1, __len2, __buf.begin(), _Distance(__buf.size()), __comp); } //将两个已排序的序列[first,middle)和[middle,last)合并成单一有序序列. //若原来是增序,现在也是递增排序,若原来是递减排序,现在也是递减排序 /* 函数功能:Merges two consecutive sorted ranges: [first,middle) and [middle,last), putting the result into the combined sorted range [first,last). 函数原型: default (1) :版本一 template <class BidirectionalIterator> void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); custom (2) :版本二 template <class BidirectionalIterator, class Compare> void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp); */ //版本一 template <class _BidirectionalIter> inline void inplace_merge(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last) { __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type, _LessThanComparable); if (__first == __middle || __middle == __last)//若有空序列,则之间返回 return; __inplace_merge_aux(__first, __middle, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } //版本二 template <class _BidirectionalIter, class _Compare> inline void inplace_merge(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Compare __comp) { __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_BidirectionalIter>::value_type, typename iterator_traits<_BidirectionalIter>::value_type); if (__first == __middle || __middle == __last) return; __inplace_merge_aux(__first, __middle, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first), __comp); } //inplace_merge函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::inplace_merge, std::sort, std::copy #include <vector> // std::vector int main () { int first[] = {5,10,15,20,25}; int second[] = {50,40,30,20,10}; std::vector<int> v(10); std::vector<int>::iterator it; std::sort (first,first+5); std::sort (second,second+5); it=std::copy (first, first+5, v.begin()); std::copy (second,second+5,it); std::inplace_merge (v.begin(),v.begin()+5,v.end()); std::cout << "The resulting vector contains:"; for (it=v.begin(); it!=v.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: The resulting vector contains: 5 10 10 15 20 20 25 30 40 50 */ // Set algorithms: includes, set_union, set_intersection, set_difference, // set_symmetric_difference. All of these algorithms have the precondition // that their input ranges are sorted and the postcondition that their output // ranges are sorted. /* 下面是计算set集合的相关算法,分别是并集set_union,差集set_difference,交集set_intersection 和对称差集set_symmetric_difference,这是个函数都提供了两个版本的函数原型 第一个版本是采用默认的排序比较方式 operator< 第二个版本是用户通过comp自行指定排序方式 注意:这四个算法接受的输入区间都是有序的,输出也是有序的 */ // Set algorithms: includes, set_union, set_intersection, set_difference, // set_symmetric_difference. All of these algorithms have the precondition // that their input ranges are sorted and the postcondition that their output // ranges are sorted. // 判断[first1, last1)是否包含[first2, last2), // 注意: 两个区间要保证有序,默认排序方式是operator<,若要自行定义排序方式,则调用第二版本; template <class _InputIter1, class _InputIter2> bool includes(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); while (__first1 != __last1 && __first2 != __last2)//遍历两个区间 if (*__first2 < *__first1)//first2小于first1表示不包含 return false;//返回FALSE else if(*__first1 < *__first2)//若first1小于first2 ++__first1;//寻找第一个区间下一个位置 else ++__first1, ++__first2;//若first2等于first1,遍历两区间的下一位置 return __first2 == __last2;//若第二个区间先到达尾端,则返回TRUE } //版本二:用户通过comp自行指定排序方式 template <class _InputIter1, class _InputIter2, class _Compare> bool includes(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first2, *__first1)) return false; else if(__comp(*__first1, *__first2)) ++__first1; else ++__first1, ++__first2; return __first2 == __last2; } //两个集合区间的并集,同样也有两个版本 //求存在于[first1, last1)或存在于[first2, last2)内的所有元素 //注意:输入区间必须是已排序 /* default (1) :默认是operator<操作的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); custom (2) :用户指定的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); */ //版本一:默认是operator<操作的排序方式 template <class _InputIter1, class _InputIter2, class _OutputIter> _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); //两个区间都尚未到达区间尾端,执行以下操作 while (__first1 != __last1 && __first2 != __last2) { /* 在两区间内分别移动迭代器,首先将元素较小者(假设为A区)记录在目标区result 移动A区迭代器使其前进;同时另一个区的迭代器不变。然后进行一次新的比较, 记录较小值,移动迭代器...直到两区间中有一个到达尾端。若两区间存在元素相等, 默认记录第一区间的元素到目标区result. */ if (*__first1 < *__first2) {//first1小于first2 *__result = *__first1;//则result初始值为first1 ++__first1;//继续第一个区间的下一个元素位置 } else if (*__first2 < *__first1) {//first2小于first1 *__result = *__first2;//第二区间元素值记录到目标区 ++__first2;//移动第二区间的迭代器 } else {//若两区间存在相等的元素,把第一区间元素记录到目标区 //同时移动两个区间的迭代器 *__result = *__first1; ++__first1; ++__first2; } ++__result;//更新目标区位置,以备进入下一次记录操作操作 } /* 只要两区间之中有一个区间到达尾端,就结束上面的while循环 以下将尚未到达尾端的区间剩余的元素拷贝到目标区 此刻,[first1, last1)和[first2, last2)至少有一个是空区间 */ return copy(__first2, __last2, copy(__first1, __last1, __result)); } //版本二:用户根据仿函数comp指定排序规则 template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare> _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) { if (__comp(*__first1, *__first2)) { *__result = *__first1; ++__first1; } else if (__comp(*__first2, *__first1)) { *__result = *__first2; ++__first2; } else { *__result = *__first1; ++__first1; ++__first2; } ++__result; } return copy(__first2, __last2, copy(__first1, __last1, __result)); } /*例子: #include <iostream> // std::cout #include <algorithm> // std::set_union, std::sort #include <vector> // std::vector int main () { int first[] = {5,10,15,20,25}; int second[] = {50,40,30,20,10}; std::vector<int> v(10); // 0 0 0 0 0 0 0 0 0 0 std::vector<int>::iterator it; std::sort (first,first+5); // 5 10 15 20 25 std::sort (second,second+5); // 10 20 30 40 50 it=std::set_union (first, first+5, second, second+5, v.begin()); // 5 10 15 20 25 30 40 50 0 0 v.resize(it-v.begin()); // 5 10 15 20 25 30 40 50 std::cout << "The union has " << (v.size()) << " elements:\n"; for (it=v.begin(); it!=v.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: The union has 8 elements: 5 10 15 20 25 30 40 50 */ //两个集合区间的交集,同样也有两个版本 //求存在于[first1, last1)且存在于[first2, last2)内的所有元素 //注意:输入区间必须是已排序,输出区间的每个元素的相对排序和第一个区间相对排序相同 /* default (1) :默认是operator<操作的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); custom (2) :用户指定的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); */ //版本一:默认是operator<操作的排序方式 template <class _InputIter1, class _InputIter2, class _OutputIter> _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); //若两个区间都尚未到达尾端,则执行以下操作 while (__first1 != __last1 && __first2 != __last2) //在两个区间分别移动迭代器,直到遇到相等元素,记录到目标区 //继续移动迭代器...直到两区间之中有到达尾端 if (*__first1 < *__first2) //第一个区间元素小于第二区间元素 ++__first1;//移动第一区间的迭代器,此时第二区间的迭代器不变 else if (*__first2 < *__first1) //第二区间的元素小于第一区间元素 ++__first2;//移动第二区间元素,此时第一区间的迭代器不变 else {//若第一区间元素等于第二区间元素 *__result = *__first1;//按第一区间的相对排序记录到目标区 //分别移动两区间的迭代器 ++__first1; ++__first2; //更新目标区迭代器,以便继续记录元素 ++__result; } //若有区间到达尾部,则停止while循环 //此时,返回目标区 return __result; } //版本二:用户根据仿函数comp指定排序规则 template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare> _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first1, *__first2)) ++__first1; else if (__comp(*__first2, *__first1)) ++__first2; else { *__result = *__first1; ++__first1; ++__first2; ++__result; } return __result; } /*例子: #include <iostream> // std::cout #include <algorithm> // std::set_intersection, std::sort #include <vector> // std::vector int main () { int first[] = {5,10,15,20,25}; int second[] = {50,40,30,20,10}; std::vector<int> v(10); // 0 0 0 0 0 0 0 0 0 0 std::vector<int>::iterator it; std::sort (first,first+5); // 5 10 15 20 25 std::sort (second,second+5); // 10 20 30 40 50 it=std::set_intersection (first, first+5, second, second+5, v.begin()); // 10 20 0 0 0 0 0 0 0 0 v.resize(it-v.begin()); // 10 20 std::cout << "The intersection has " << (v.size()) << " elements:\n"; for (it=v.begin(); it!=v.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: The intersection has 2 elements: 10 20 */ //两个集合区间的差集,同样也有两个版本 //求存在于[first1, last1)但不存在于[first2, last2)内的所有元素 //注意:输入区间必须是已排序,输出区间的每个元素的相对排序和第一个区间相对排序相同 /* default (1) :默认是operator<操作的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); custom (2) :用户指定的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); */ //版本一:默认是operator<操作的排序方式 template <class _InputIter1, class _InputIter2, class _OutputIter> _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); //若两个区间都尚未到达尾端,则执行以下操作 while (__first1 != __last1 && __first2 != __last2) /* 在两个区间分别移动迭代器,当第一区间元素等于第二区间元素时,表示两区间共同存在该元素 则同时移动迭代器; 当第一区间元素大于第二区间元素时,就让第二区间迭代器前进; 第一区间元素小于第二区间元素时,把第一区间元素记录到目标区 继续移动迭代器...直到两区间之中有到达尾端 */ if (*__first1 < *__first2) {//第一区间元素小于第二区间元素 *__result = *__first1;//把第一区间元素记录到目标区 ++__first1;//移动第一区间迭代器 ++__result;//跟新目标区,以便继续记录数据 } else if (*__first2 < *__first1)//当第一区间的元素大于第二区间的元素 ++__first2;//移动第二区间迭代器,注意:这里不记录任何元素 else {//若两区间的元素相等时,同时移动两区间的迭代器 ++__first1; ++__first2; } //若第二区间先到达尾端,则把第一区间剩余的元素复制到目标区 return copy(__first1, __last1, __result); } //版本二:用户根据仿函数comp指定排序规则 template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare> _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first1, *__first2)) { *__result = *__first1; ++__first1; ++__result; } else if (__comp(*__first2, *__first1)) ++__first2; else { ++__first1; ++__first2; } return copy(__first1, __last1, __result); } /*例子: #include <iostream> // std::cout #include <algorithm> // std::set_difference, std::sort #include <vector> // std::vector int main () { int first[] = {5,10,15,20,25}; int second[] = {50,40,30,20,10}; std::vector<int> v(10); // 0 0 0 0 0 0 0 0 0 0 std::vector<int>::iterator it; std::sort (first,first+5); // 5 10 15 20 25 std::sort (second,second+5); // 10 20 30 40 50 it=std::set_difference (first, first+5, second, second+5, v.begin()); // 5 15 25 0 0 0 0 0 0 0 v.resize(it-v.begin()); // 5 15 25 std::cout << "The difference has " << (v.size()) << " elements:\n"; for (it=v.begin(); it!=v.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: The difference has 3 elements: 5 15 25 */ //两个集合区间的对称差集,同样也有两个版本 //求存在于[first1, last1)但不存在于[first2, last2)内的所有元素以及出现在[first2, last2)但不出现在[first1, last1) //注意:输入区间必须是已排序 /* default (1) :默认是operator<操作的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); custom (2) :用户指定的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); */ //版本一:默认是operator<操作的排序方式 template <class _InputIter1, class _InputIter2, class _OutputIter> _OutputIter set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); //若两个区间都尚未到达尾端,则执行下面的操作 while (__first1 != __last1 && __first2 != __last2) /* 情况1:若两区间元素相等,则同时移动两区间的迭代器. 情况2:若第一区间的元素小于第二区间元素,则把第一区间元素记录到目标区,且移动第一区间迭代器. 情况3:若第一区间的元素大于第二区间元素,则把第二区间元素记录到目标区,且移动第二区间迭代器. */ if (*__first1 < *__first2) {//属于情况2 *__result = *__first1;//把第一区间元素记录到目标区 ++__first1;//移动第一区间迭代器.此时第二区间迭代器不变 ++__result; } else if (*__first2 < *__first1) {//属于情况3 *__result = *__first2;//把第二区间元素记录到目标区 ++__first2;//移动第二区间迭代器.此时第一区间迭代器不变 ++__result; } else {//属于情况1 //同时移动两区间的迭代器 ++__first1; ++__first2; } /* 只要两区间之中有一个区间到达尾端,就结束上面的while循环 以下将尚未到达尾端的区间剩余的元素拷贝到目标区 此刻,[first1, last1)和[first2, last2)至少有一个是空区间 */ return copy(__first2, __last2, copy(__first1, __last1, __result)); } //版本二:用户根据仿函数comp指定排序规则 template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare> _OutputIter set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first1, *__first2)) { *__result = *__first1; ++__first1; ++__result; } else if (__comp(*__first2, *__first1)) { *__result = *__first2; ++__first2; ++__result; } else { ++__first1; ++__first2; } return copy(__first2, __last2, copy(__first1, __last1, __result)); } /*例子: #include <iostream> // std::cout #include <algorithm> // std::set_symmetric_difference, std::sort #include <vector> // std::vector int main () { int first[] = {5,10,15,20,25}; int second[] = {50,40,30,20,10}; std::vector<int> v(10); // 0 0 0 0 0 0 0 0 0 0 std::vector<int>::iterator it; std::sort (first,first+5); // 5 10 15 20 25 std::sort (second,second+5); // 10 20 30 40 50 it=std::set_symmetric_difference (first, first+5, second, second+5, v.begin()); // 5 15 25 30 40 50 0 0 0 0 v.resize(it-v.begin()); // 5 15 25 30 40 50 std::cout << "The symmetric difference has " << (v.size()) << " elements:\n"; for (it=v.begin(); it!=v.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: The symmetric difference has 6 elements: 5 15 25 30 40 50 */ // min_element and max_element, with and without an explicitly supplied // comparison function. //返回序列[first,last)中最大元素的位置 /* default (1):版本一 template <class ForwardIterator> ForwardIterator max_element (ForwardIterator first, ForwardIterator last); custom (2):版本二 template <class ForwardIterator, class Compare> ForwardIterator max_element (ForwardIterator first, ForwardIterator last, Compare comp); */ //版本一: template <class _ForwardIter> _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _LessThanComparable); if (__first == __last) return __first;//若为空,直接返回 _ForwardIter __result = __first;//若不为空,从第一个元素开始,即把第一个元素暂时保存为最大值 while (++__first != __last) //按顺序查找最大值 if (*__result < *__first)//若有更大的值 __result = __first;//则更新最大值位置 return __result;//返回最大值位置 } //版本二 template <class _ForwardIter, class _Compare> _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return __first; _ForwardIter __result = __first; while (++__first != __last) if (__comp(*__result, *__first)) __result = __first; return __result; } //返回序列[first,last)中最小元素的位置 /* default (1):版本一 template <class ForwardIterator> ForwardIterator min_element (ForwardIterator first, ForwardIterator last); custom (2):版本二 template <class ForwardIterator, class Compare> ForwardIterator min_element (ForwardIterator first, ForwardIterator last, Compare comp); */ //版本一: template <class _ForwardIter> _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _LessThanComparable); if (__first == __last) return __first;//若为空,直接返回 _ForwardIter __result = __first;//若不为空,从第一个元素开始,即把第一个元素暂时保存为最小值 while (++__first != __last) //按顺序查找最小值 if (*__first < *__result)//若存在更小的值 __result = __first;//则更新最小值位置 return __result;//返回最小值位置 } //版本二 template <class _ForwardIter, class _Compare> _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return __first; _ForwardIter __result = __first; while (++__first != __last) if (__comp(*__first, *__result)) __result = __first; return __result; } //max_element和min_element函数举例 /* #include <iostream> // std::cout #include <algorithm> // std::min_element, std::max_element bool myfn(int i, int j) { return i<j; } struct myclass { bool operator() (int i,int j) { return i<j; } } myobj; int main () { int myints[] = {3,7,2,5,6,4,9}; // using default comparison: std::cout << "The smallest element is " << *std::min_element(myints,myints+7) << '\n'; std::cout << "The largest element is " << *std::max_element(myints,myints+7) << '\n'; // using function myfn as comp: std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myfn) << '\n'; std::cout << "The largest element is " << *std::max_element(myints,myints+7,myfn) << '\n'; // using object myobj as comp: std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myobj) << '\n'; std::cout << "The largest element is " << *std::max_element(myints,myints+7,myobj) << '\n'; return 0; } Output: The smallest element is 2 The largest element is 9 The smallest element is 2 The largest element is 9 The smallest element is 2 The largest element is 9 */ // next_permutation and prev_permutation, with and without an explicitly // supplied comparison function. //next_permutation获取[first,last)区间所标示序列的下一个排列组合,若果没有下一个排序组合,则返回false;否则返回true; /* 函数功能:Rearranges the elements in the range [first,last) into the next lexicographically greater permutation. 函数原型: default (1) :版本一采用less-than操作符 template <class BidirectionalIterator> bool next_permutation (BidirectionalIterator first, BidirectionalIterator last); custom (2) :版本二采用仿函数comp决定 template <class BidirectionalIterator, class Compare> bool next_permutation (BidirectionalIterator first, BidirectionalIterator last, Compare comp); */ //版本一 template <class _BidirectionalIter> bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type, _LessThanComparable); if (__first == __last) return false;//若为空,则返回false _BidirectionalIter __i = __first; ++__i; if (__i == __last)//区间只有一个元素 return false; //若区间元素个数不小于两个 __i = __last;//i指向尾端 --__i;//不断后移 for(;;) { //下面两行是让ii和i成为相邻的元素 //其中i为第一个元素,ii为第二个元素 _BidirectionalIter __ii = __i;// --__i; //以下在相邻元素判断 if (*__i < *__ii) {//若前一个元素小于后一个元素, //则再从最尾端开始往前检查,找出第一个大于*i的元素,令该元素为*j,将*i和*j交换 //再将ii之后的所有元素颠倒排序 _BidirectionalIter __j = __last;//令j指向最尾端 while (!(*__i < *--__j))//由尾端往前检查,直到遇到比*i大的元素 {} iter_swap(__i, __j);//交换迭代器i和迭代器j所指的元素 reverse(__ii, __last);//将ii之后的元素全部逆向重排 return true; } if (__i == __first) {//进行到最前面 reverse(__first, __last);//整个区间全部逆向重排 return false; } } } //版本二 template <class _BidirectionalIter, class _Compare> bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last, _Compare __comp) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_BidirectionalIter>::value_type, typename iterator_traits<_BidirectionalIter>::value_type); if (__first == __last) return false; _BidirectionalIter __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; for(;;) { _BidirectionalIter __ii = __i; --__i; if (__comp(*__i, *__ii)) { _BidirectionalIter __j = __last; while (!__comp(*__i, *--__j)) {} iter_swap(__i, __j); reverse(__ii, __last); return true; } if (__i == __first) { reverse(__first, __last); return false; } } } //next_permutation函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::next_permutation, std::sort int main () { int myints[] = {1,2,3,4}; std::sort (myints,myints+4); std::cout << "The 3! possible permutations with 3 elements:\n"; do { std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] <<' ' << myints[3]<< '\n'; } while ( std::next_permutation(myints,myints+4) ); //std::next_permutation(myints,myints+4); std::cout << "After loop: " << myints[0] << ' ' << myints[1] << ' ' << myints[2] << ' ' << myints[3]<<'\n'; return 0; } Output: The 3! possible permutations with 3 elements: 1 2 3 4 1 2 4 3 1 3 2 4 1 3 4 2 1 4 2 3 1 4 3 2 2 1 3 4 2 1 4 3 2 3 1 4 2 3 4 1 2 4 1 3 2 4 3 1 3 1 2 4 3 1 4 2 3 2 1 4 3 2 4 1 3 4 1 2 3 4 2 1 4 1 2 3 4 1 3 2 4 2 1 3 4 2 3 1 4 3 1 2 4 3 2 1 After loop: 1 2 3 4 */ //prev_permutation获取[first,last)区间所标示序列的上一个排列组合,若果没有上一个排序组合,则返回false;否则返回true; /* 函数功能:Rearranges the elements in the range [first,last) into the previous lexicographically-ordered permutation. 函数原型: default (1) :版本一采用less-than操作符 template <class BidirectionalIterator> bool prev_permutation (BidirectionalIterator first, BidirectionalIterator last ); custom (2) :版本二采用仿函数comp template <class BidirectionalIterator, class Compare> bool prev_permutation (BidirectionalIterator first, BidirectionalIterator last, Compare comp); */ //版本一 template <class _BidirectionalIter> bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type, _LessThanComparable); if (__first == __last) return false;//若区间为空,返回false _BidirectionalIter __i = __first; ++__i; if (__i == __last)//区间只有一个元素 return false;//返回false //若区间元素个数不小于两个 __i = __last; --__i; for(;;) { //下面两行是让ii和i成为相邻的元素 //其中i为第一个元素,ii为第二个元素 _BidirectionalIter __ii = __i; --__i; //以下在相邻元素判断 if (*__ii < *__i) {//若前一个元素大于后一个元素, //则再从最尾端开始往前检查,找出第一个小于*i的元素,令该元素为*j,将*i和*j交换 //再将ii之后的所有元素颠倒排序 _BidirectionalIter __j = __last;//令j指向最尾端 while (!(*--__j < *__i))//由尾端往前检查,直到遇到比*i小的元素 {} iter_swap(__i, __j); //交换迭代器i和迭代器j所指的元素 reverse(__ii, __last);//将ii之后的元素全部逆向重排 return true; } if (__i == __first) {//进行到最前面 reverse(__first, __last);//把区间所有元素逆向重排 return false; } } } //版本二 template <class _BidirectionalIter, class _Compare> bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last, _Compare __comp) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_BidirectionalIter>::value_type, typename iterator_traits<_BidirectionalIter>::value_type); if (__first == __last) return false; _BidirectionalIter __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; for(;;) { _BidirectionalIter __ii = __i; --__i; if (__comp(*__ii, *__i)) { _BidirectionalIter __j = __last; while (!__comp(*--__j, *__i)) {} iter_swap(__i, __j); reverse(__ii, __last); return true; } if (__i == __first) { reverse(__first, __last); return false; } } } //prev_permutation函数举例 /* #include <iostream> // std::cout #include <algorithm> // std::next_permutation, std::sort, std::reverse int main () { int myints[] = {1,2,3}; std::sort (myints,myints+3); std::reverse (myints,myints+3); std::cout << "The 3! possible permutations with 3 elements:\n"; do { std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n'; } while ( std::prev_permutation(myints,myints+3) ); std::cout << "After loop: " << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n'; return 0; } Output: The 3! possible permutations with 3 elements: 3 2 1 3 1 2 2 3 1 2 1 3 1 3 2 1 2 3 After loop: 3 2 1 */ // find_first_of, with and without an explicitly supplied comparison function. //以[first2,last2)区间内的某些元素为查找目标,寻找他们在[first1,last1)区间首次出现的位置 //find_first_of函数有两个版本: //版本一:提供默认的equality操作operator== //版本二:提供用户自行指定的操作规则comp /* 函数功能:Returns an iterator to the first element in the range [first1,last1) that matches any of the elements in [first2,last2). If no such element is found, the function returns last1. 函数原型: equality (1):版本一 template <class ForwardIterator1, class ForwardIterator2> ForwardIterator1 find_first_of (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); predicate (2):版本二 template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 find_first_of (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); */ //版本一:提供默认的equality操作operator== template <class _InputIter, class _ForwardIter> _InputIter find_first_of(_InputIter __first1, _InputIter __last1, _ForwardIter __first2, _ForwardIter __last2) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_InputIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); for ( ; __first1 != __last1; ++__first1) //若序列一不为空,则遍历序列一,每次指定一个元素 //以下,根据序列二的每个元素 for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) if (*__first1 == *__iter)//若序列一的元素等于序列二的元素,则表示找到 return __first1;//返回找到的位置 return __last1;//否则没找到 } //版本二:提供用户自行指定的操作规则comp template <class _InputIter, class _ForwardIter, class _BinaryPredicate> _InputIter find_first_of(_InputIter __first1, _InputIter __last1, _ForwardIter __first2, _ForwardIter __last2, _BinaryPredicate __comp) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_InputIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); for ( ; __first1 != __last1; ++__first1) for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) if (__comp(*__first1, *__iter)) return __first1; return __last1; } //find_first_of函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::find_first_of #include <vector> // std::vector #include <cctype> // std::tolower bool comp_case_insensitive (char c1, char c2) { return (std::tolower(c1)==std::tolower(c2)); } int main () { int mychars[] = {'a','b','c','A','B','C'}; std::vector<char> haystack (mychars,mychars+6); std::vector<char>::iterator it; int needle[] = {'A','B','C'}; // using default comparison: it = find_first_of (haystack.begin(), haystack.end(), needle, needle+3); if (it!=haystack.end()) std::cout << "The first match is: " << *it << '\n'; // using predicate comparison: it = find_first_of (haystack.begin(), haystack.end(), needle, needle+3, comp_case_insensitive); if (it!=haystack.end()) std::cout << "The first match is: " << *it << '\n'; return 0; } Output: The first match is: A The first match is: a */ // find_end, with and without an explicitly supplied comparison function. // Search [first2, last2) as a subsequence in [first1, last1), and return // the *last* possible match. Note that find_end for bidirectional iterators // is much faster than for forward iterators. // find_end for forward iterators. //若萃取出来的迭代器类型为正向迭代器forward_iterator_tag,则调用此函数 template <class _ForwardIter1, class _ForwardIter2> _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2, forward_iterator_tag, forward_iterator_tag) { if (__first2 == __last2)//若第二个区间为空 return __last1;//则直接返回第一个区间的尾端 else { _ForwardIter1 __result = __last1; while (1) { //以下利用search函数查找出某个子序列的首次出现点;若找不到直接返回last1 _ForwardIter1 __new_result = search(__first1, __last1, __first2, __last2); if (__new_result == __last1)//若返回的位置为尾端,则表示没找到 return __result;//返回last1 else {//若在[first1,last1)中找到[first2,last2)首次出现的位置,继续准备下一次查找 __result = __new_result;//更新返回的位置 __first1 = __new_result;//更新查找的起始位置 ++__first1;//确定正确查找起始位置 } } } } //版本二:指定规则 template <class _ForwardIter1, class _ForwardIter2, class _BinaryPredicate> _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2, forward_iterator_tag, forward_iterator_tag, _BinaryPredicate __comp) { if (__first2 == __last2) return __last1; else { _ForwardIter1 __result = __last1; while (1) { _ForwardIter1 __new_result = search(__first1, __last1, __first2, __last2, __comp); if (__new_result == __last1) return __result; else { __result = __new_result; __first1 = __new_result; ++__first1; } } } } // find_end for bidirectional iterators. Requires partial specialization. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION //若萃取出来的迭代器类型为双向迭代器bidirectional_iterator_tag,则调用此函数 template <class _BidirectionalIter1, class _BidirectionalIter2> _BidirectionalIter1 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag) { __STL_REQUIRES(_BidirectionalIter1, _BidirectionalIterator); __STL_REQUIRES(_BidirectionalIter2, _BidirectionalIterator); //利用反向迭代器很快就可以找到 typedef reverse_iterator<_BidirectionalIter1> _RevIter1; typedef reverse_iterator<_BidirectionalIter2> _RevIter2; _RevIter1 __rlast1(__first1); _RevIter2 __rlast2(__first2); //查找时将序列一和序列二逆方向 _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, _RevIter2(__last2), __rlast2); if (__rresult == __rlast1)//表示没找到 return __last1; else {//找到了 _BidirectionalIter1 __result = __rresult.base();//转会正常迭代器 advance(__result, -distance(__first2, __last2));//调整回到子序列的起始位置 return __result; } } //版本二:指定规则comp template <class _BidirectionalIter1, class _BidirectionalIter2, class _BinaryPredicate> _BidirectionalIter1 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag, _BinaryPredicate __comp) { __STL_REQUIRES(_BidirectionalIter1, _BidirectionalIterator); __STL_REQUIRES(_BidirectionalIter2, _BidirectionalIterator); typedef reverse_iterator<_BidirectionalIter1> _RevIter1; typedef reverse_iterator<_BidirectionalIter2> _RevIter2; _RevIter1 __rlast1(__first1); _RevIter2 __rlast2(__first2); _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, _RevIter2(__last2), __rlast2, __comp); if (__rresult == __rlast1) return __last1; else { _BidirectionalIter1 __result = __rresult.base(); advance(__result, -distance(__first2, __last2)); return __result; } } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // Dispatching functions for find_end. //find_end函数有两个版本: //版本一:提供默认的equality操作operator== //版本二:提供用户自行指定的操作规则comp //注意:这里也有偏特化的知识 /*函数功能:Searches the range [first1,last1) for the last occurrence of the sequence defined by [first2,last2), and returns an iterator to its first element, or last1 if no occurrences are found. 函数原型: equality (1):版本一 template <class ForwardIterator1, class ForwardIterator2> ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); predicate (2):版本二 template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); */ //对外接口的版本一 template <class _ForwardIter1, class _ForwardIter2> inline _ForwardIter1 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2) { __STL_REQUIRES(_ForwardIter1, _ForwardIterator); __STL_REQUIRES(_ForwardIter2, _ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); //首先通过iterator_traits萃取出first1和first2的迭代器类型 //根据不同的迭代器类型调用不同的函数 return __find_end(__first1, __last1, __first2, __last2, __ITERATOR_CATEGORY(__first1), __ITERATOR_CATEGORY(__first2)); } //对外接口的版本一 template <class _ForwardIter1, class _ForwardIter2, class _BinaryPredicate> inline _ForwardIter1 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2, _BinaryPredicate __comp) { __STL_REQUIRES(_ForwardIter1, _ForwardIterator); __STL_REQUIRES(_ForwardIter2, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); //首先通过iterator_traits萃取出first1和first2的迭代器类型 //根据不同的迭代器类型调用不同的函数 return __find_end(__first1, __last1, __first2, __last2, __ITERATOR_CATEGORY(__first1), __ITERATOR_CATEGORY(__first2), __comp); } //find_end函数举例: /* #include <iostream> // std::cout #include <algorithm> // std::find_end #include <vector> // std::vector bool myfunction (int i, int j) { return (i==j); } int main () { int myints[] = {1,2,3,4,5,1,2,3,4,5}; std::vector<int> haystack (myints,myints+10); int needle1[] = {1,2,3}; // using default comparison: std::vector<int>::iterator it; it = std::find_end (haystack.begin(), haystack.end(), needle1, needle1+3); if (it!=haystack.end()) std::cout << "needle1 last found at position " << (it-haystack.begin()) << '\n'; int needle2[] = {4,5,1}; // using predicate comparison: it = std::find_end (haystack.begin(), haystack.end(), needle2, needle2+3, myfunction); if (it!=haystack.end()) std::cout << "needle2 last found at position " << (it-haystack.begin()) << '\n'; return 0; } Output: needle1 found at position 5 needle2 found at position 3 */ // is_heap, a predicate testing whether or not a range is // a heap. This function is an extension, not part of the C++ // standard. template <class _RandomAccessIter, class _Distance> bool __is_heap(_RandomAccessIter __first, _Distance __n) { _Distance __parent = 0; for (_Distance __child = 1; __child < __n; ++__child) { if (__first[__parent] < __first[__child]) return false; if ((__child & 1) == 0) ++__parent; } return true; } template <class _RandomAccessIter, class _Distance, class _StrictWeakOrdering> bool __is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp, _Distance __n) { _Distance __parent = 0; for (_Distance __child = 1; __child < __n; ++__child) { if (__comp(__first[__parent], __first[__child])) return false; if ((__child & 1) == 0) ++__parent; } return true; } template <class _RandomAccessIter> inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); return __is_heap(__first, __last - __first); } template <class _RandomAccessIter, class _StrictWeakOrdering> inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last, _StrictWeakOrdering __comp) { __STL_REQUIRES(_RandomAccessIter, _RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_StrictWeakOrdering, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); return __is_heap(__first, __comp, __last - __first); } // is_sorted, a predicated testing whether a range is sorted in // nondescending order. This is an extension, not part of the C++ // standard. template <class _ForwardIter> bool is_sorted(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _LessThanComparable); if (__first == __last) return true; _ForwardIter __next = __first; for (++__next; __next != __last; __first = __next, ++__next) { if (*__next < *__first) return false; } return true; } template <class _ForwardIter, class _StrictWeakOrdering> bool is_sorted(_ForwardIter __first, _ForwardIter __last, _StrictWeakOrdering __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_StrictWeakOrdering, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return true; _ForwardIter __next = __first; for (++__next; __next != __last; __first = __next, ++__next) { if (__comp(*__next, *__first)) return false; } return true; } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1209 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_ALGO_H */ // Local Variables: // mode:C++ // End: ~~~ 参考资料: 《STL源码剖析》侯捷
';

STL算法之set集合算法

最后更新于:2022-04-01 15:51:25

### 前言   本节介绍set集合的相关算法,分别是并集set_union,差集set_difference,交集set_intersection 和对称差集set_symmetric_difference,这是个函数都提供了两个版本的函数原型:第一个版本是采用默认的排序比较方式operator<;第二个版本是用户通过仿函数comp自行指定排序方式。注意:这四个算法接受的输入区间都是有序的,输出也是有序的。下面对set算法进行剖析,具体注释详见源码,同时给出例子说明该算法的功能。本文源码摘自SGI STL中的<stl_algo.h>文件。 ### set算法源码剖析 ~~~ /* 下面是计算set集合的相关算法,分别是并集set_union,差集set_difference,交集set_intersection 和对称差集set_symmetric_difference,这是个函数都提供了两个版本的函数原型 第一个版本是采用默认的排序比较方式 operator< 第二个版本是用户通过comp自行指定排序方式 注意:这四个算法接受的输入区间都是有序的,输出也是有序的 */ // Set algorithms: includes, set_union, set_intersection, set_difference, // set_symmetric_difference. All of these algorithms have the precondition // that their input ranges are sorted and the postcondition that their output // ranges are sorted. // 判断[first1, last1)是否包含[first2, last2), // 注意: 两个区间要保证有序,默认排序方式是operator<,若要自行定义排序方式,则调用第二版本; template <class _InputIter1, class _InputIter2> bool includes(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); while (__first1 != __last1 && __first2 != __last2)//遍历两个区间 if (*__first2 < *__first1)//first2小于first1表示不包含 return false;//返回FALSE else if(*__first1 < *__first2)//若first1小于first2 ++__first1;//寻找第一个区间下一个位置 else ++__first1, ++__first2;//若first2等于first1,遍历两区间的下一位置 return __first2 == __last2;//若第二个区间先到达尾端,则返回TRUE } //版本二:用户通过comp自行指定排序方式 template <class _InputIter1, class _InputIter2, class _Compare> bool includes(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first2, *__first1)) return false; else if(__comp(*__first1, *__first2)) ++__first1; else ++__first1, ++__first2; return __first2 == __last2; } //两个集合区间的并集,同样也有两个版本 //求存在于[first1, last1)或存在于[first2, last2)内的所有元素 //注意:输入区间必须是已排序 /* default (1) :默认是operator<操作的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); custom (2) :用户指定的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); */ //版本一:默认是operator<操作的排序方式 template <class _InputIter1, class _InputIter2, class _OutputIter> _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); //两个区间都尚未到达区间尾端,执行以下操作 while (__first1 != __last1 && __first2 != __last2) { /* 在两区间内分别移动迭代器,首先将元素较小者(假设为A区)记录在目标区result 移动A区迭代器使其前进;同时另一个区的迭代器不变。然后进行一次新的比较, 记录较小值,移动迭代器...直到两区间中有一个到达尾端。若两区间存在元素相等, 默认记录第一区间的元素到目标区result. */ if (*__first1 < *__first2) {//first1小于first2 *__result = *__first1;//则result初始值为first1 ++__first1;//继续第一个区间的下一个元素位置 } else if (*__first2 < *__first1) {//first2小于first1 *__result = *__first2;//第二区间元素值记录到目标区 ++__first2;//移动第二区间的迭代器 } else {//若两区间存在相等的元素,把第一区间元素记录到目标区 //同时移动两个区间的迭代器 *__result = *__first1; ++__first1; ++__first2; } ++__result;//更新目标区位置,以备进入下一次记录操作操作 } /* 只要两区间之中有一个区间到达尾端,就结束上面的while循环 以下将尚未到达尾端的区间剩余的元素拷贝到目标区 此刻,[first1, last1)和[first2, last2)至少有一个是空区间 */ return copy(__first2, __last2, copy(__first1, __last1, __result)); } //版本二:用户根据仿函数comp指定排序规则 template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare> _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) { if (__comp(*__first1, *__first2)) { *__result = *__first1; ++__first1; } else if (__comp(*__first2, *__first1)) { *__result = *__first2; ++__first2; } else { *__result = *__first1; ++__first1; ++__first2; } ++__result; } return copy(__first2, __last2, copy(__first1, __last1, __result)); } /*例子: #include <iostream> // std::cout #include <algorithm> // std::set_union, std::sort #include <vector> // std::vector int main () { int first[] = {5,10,15,20,25}; int second[] = {50,40,30,20,10}; std::vector<int> v(10); // 0 0 0 0 0 0 0 0 0 0 std::vector<int>::iterator it; std::sort (first,first+5); // 5 10 15 20 25 std::sort (second,second+5); // 10 20 30 40 50 it=std::set_union (first, first+5, second, second+5, v.begin()); // 5 10 15 20 25 30 40 50 0 0 v.resize(it-v.begin()); // 5 10 15 20 25 30 40 50 std::cout << "The union has " << (v.size()) << " elements:\n"; for (it=v.begin(); it!=v.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: The union has 8 elements: 5 10 15 20 25 30 40 50 */ //两个集合区间的交集,同样也有两个版本 //求存在于[first1, last1)且存在于[first2, last2)内的所有元素 //注意:输入区间必须是已排序,输出区间的每个元素的相对排序和第一个区间相对排序相同 /* default (1) :默认是operator<操作的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); custom (2) :用户指定的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); */ //版本一:默认是operator<操作的排序方式 template <class _InputIter1, class _InputIter2, class _OutputIter> _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); //若两个区间都尚未到达尾端,则执行以下操作 while (__first1 != __last1 && __first2 != __last2) //在两个区间分别移动迭代器,直到遇到相等元素,记录到目标区 //继续移动迭代器...直到两区间之中有到达尾端 if (*__first1 < *__first2) //第一个区间元素小于第二区间元素 ++__first1;//移动第一区间的迭代器,此时第二区间的迭代器不变 else if (*__first2 < *__first1) //第二区间的元素小于第一区间元素 ++__first2;//移动第二区间元素,此时第一区间的迭代器不变 else {//若第一区间元素等于第二区间元素 *__result = *__first1;//按第一区间的相对排序记录到目标区 //分别移动两区间的迭代器 ++__first1; ++__first2; //更新目标区迭代器,以便继续记录元素 ++__result; } //若有区间到达尾部,则停止while循环 //此时,返回目标区 return __result; } //版本二:用户根据仿函数comp指定排序规则 template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare> _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first1, *__first2)) ++__first1; else if (__comp(*__first2, *__first1)) ++__first2; else { *__result = *__first1; ++__first1; ++__first2; ++__result; } return __result; } /*例子: #include <iostream> // std::cout #include <algorithm> // std::set_intersection, std::sort #include <vector> // std::vector int main () { int first[] = {5,10,15,20,25}; int second[] = {50,40,30,20,10}; std::vector<int> v(10); // 0 0 0 0 0 0 0 0 0 0 std::vector<int>::iterator it; std::sort (first,first+5); // 5 10 15 20 25 std::sort (second,second+5); // 10 20 30 40 50 it=std::set_intersection (first, first+5, second, second+5, v.begin()); // 10 20 0 0 0 0 0 0 0 0 v.resize(it-v.begin()); // 10 20 std::cout << "The intersection has " << (v.size()) << " elements:\n"; for (it=v.begin(); it!=v.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: The intersection has 2 elements: 10 20 */ //两个集合区间的差集,同样也有两个版本 //求存在于[first1, last1)但不存在于[first2, last2)内的所有元素 //注意:输入区间必须是已排序,输出区间的每个元素的相对排序和第一个区间相对排序相同 /* default (1) :默认是operator<操作的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); custom (2) :用户指定的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); */ //版本一:默认是operator<操作的排序方式 template <class _InputIter1, class _InputIter2, class _OutputIter> _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); //若两个区间都尚未到达尾端,则执行以下操作 while (__first1 != __last1 && __first2 != __last2) /* 在两个区间分别移动迭代器,当第一区间元素等于第二区间元素时,表示两区间共同存在该元素 则同时移动迭代器; 当第一区间元素大于第二区间元素时,就让第二区间迭代器前进; 第一区间元素小于第二区间元素时,把第一区间元素记录到目标区 继续移动迭代器...直到两区间之中有到达尾端 */ if (*__first1 < *__first2) {//第一区间元素小于第二区间元素 *__result = *__first1;//把第一区间元素记录到目标区 ++__first1;//移动第一区间迭代器 ++__result;//跟新目标区,以便继续记录数据 } else if (*__first2 < *__first1)//当第一区间的元素大于第二区间的元素 ++__first2;//移动第二区间迭代器,注意:这里不记录任何元素 else {//若两区间的元素相等时,同时移动两区间的迭代器 ++__first1; ++__first2; } //若第二区间先到达尾端,则把第一区间剩余的元素复制到目标区 return copy(__first1, __last1, __result); } //版本二:用户根据仿函数comp指定排序规则 template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare> _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first1, *__first2)) { *__result = *__first1; ++__first1; ++__result; } else if (__comp(*__first2, *__first1)) ++__first2; else { ++__first1; ++__first2; } return copy(__first1, __last1, __result); } /*例子: #include <iostream> // std::cout #include <algorithm> // std::set_difference, std::sort #include <vector> // std::vector int main () { int first[] = {5,10,15,20,25}; int second[] = {50,40,30,20,10}; std::vector<int> v(10); // 0 0 0 0 0 0 0 0 0 0 std::vector<int>::iterator it; std::sort (first,first+5); // 5 10 15 20 25 std::sort (second,second+5); // 10 20 30 40 50 it=std::set_difference (first, first+5, second, second+5, v.begin()); // 5 15 25 0 0 0 0 0 0 0 v.resize(it-v.begin()); // 5 15 25 std::cout << "The difference has " << (v.size()) << " elements:\n"; for (it=v.begin(); it!=v.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: The difference has 3 elements: 5 15 25 */ //两个集合区间的对称差集,同样也有两个版本 //求存在于[first1, last1)但不存在于[first2, last2)内的所有元素以及出现在[first2, last2)但不出现在[first1, last1) //注意:输入区间必须是已排序 /* default (1) :默认是operator<操作的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); custom (2) :用户指定的排序方式 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); */ //版本一:默认是operator<操作的排序方式 template <class _InputIter1, class _InputIter2, class _OutputIter> _OutputIter set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); //若两个区间都尚未到达尾端,则执行下面的操作 while (__first1 != __last1 && __first2 != __last2) /* 情况1:若两区间元素相等,则同时移动两区间的迭代器. 情况2:若第一区间的元素小于第二区间元素,则把第一区间元素记录到目标区,且移动第一区间迭代器. 情况3:若第一区间的元素大于第二区间元素,则把第二区间元素记录到目标区,且移动第二区间迭代器. */ if (*__first1 < *__first2) {//属于情况2 *__result = *__first1;//把第一区间元素记录到目标区 ++__first1;//移动第一区间迭代器.此时第二区间迭代器不变 ++__result; } else if (*__first2 < *__first1) {//属于情况3 *__result = *__first2;//把第二区间元素记录到目标区 ++__first2;//移动第二区间迭代器.此时第一区间迭代器不变 ++__result; } else {//属于情况1 //同时移动两区间的迭代器 ++__first1; ++__first2; } /* 只要两区间之中有一个区间到达尾端,就结束上面的while循环 以下将尚未到达尾端的区间剩余的元素拷贝到目标区 此刻,[first1, last1)和[first2, last2)至少有一个是空区间 */ return copy(__first2, __last2, copy(__first1, __last1, __result)); } //版本二:用户根据仿函数comp指定排序规则 template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare> _OutputIter set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first1, *__first2)) { *__result = *__first1; ++__first1; ++__result; } else if (__comp(*__first2, *__first1)) { *__result = *__first2; ++__first2; ++__result; } else { ++__first1; ++__first2; } return copy(__first2, __last2, copy(__first1, __last1, __result)); } /*例子: #include <iostream> // std::cout #include <algorithm> // std::set_symmetric_difference, std::sort #include <vector> // std::vector int main () { int first[] = {5,10,15,20,25}; int second[] = {50,40,30,20,10}; std::vector<int> v(10); // 0 0 0 0 0 0 0 0 0 0 std::vector<int>::iterator it; std::sort (first,first+5); // 5 10 15 20 25 std::sort (second,second+5); // 10 20 30 40 50 it=std::set_symmetric_difference (first, first+5, second, second+5, v.begin()); // 5 15 25 30 40 50 0 0 0 0 v.resize(it-v.begin()); // 5 15 25 30 40 50 std::cout << "The symmetric difference has " << (v.size()) << " elements:\n"; for (it=v.begin(); it!=v.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: The symmetric difference has 6 elements: 5 15 25 30 40 50 */ ~~~ 参考资料: 《STL源码剖析》侯捷
';

基本算法stl_algobase.h

最后更新于:2022-04-01 15:51:23

### 前言   在STL中,算法是经常被使用的,算法在整个STL中起到非常重要的作用。本节介绍的是一些基本算法,包含equal,fill,fill_n,iter_swap,lexicographical_compare,max,min,mismatch,swap,copy,copy_backward,copy_n。其中一个比较重要的算法就是copy,针对copy的剖析在源码中可以看到详细的注解。本文剖析的源码出自SGL STL中的<stl_algobase.h>文件。 ### 基本算法剖析 ~~~ #ifndef __SGI_STL_INTERNAL_ALGOBASE_H #define __SGI_STL_INTERNAL_ALGOBASE_H #ifndef __STL_CONFIG_H #include <stl_config.h> #endif #ifndef __SGI_STL_INTERNAL_RELOPS #include <stl_relops.h>//这个头文件是提供操作符重载 #endif #ifndef __SGI_STL_INTERNAL_PAIR_H #include <stl_pair.h> #endif #ifndef __TYPE_TRAITS_H #include <type_traits.h>//这个文件提供萃取技术 #endif #include <string.h> #include <limits.h> #include <stdlib.h> #include <stddef.h> #include <new.h> #ifdef __STL_USE_NEW_IOSTREAMS #include <iosfwd> #else /* __STL_USE_NEW_IOSTREAMS */ #include <iostream.h> #endif /* __STL_USE_NEW_IOSTREAMS */ #ifndef __SGI_STL_INTERNAL_ITERATOR_H #include <stl_iterator_base.h> #include <stl_iterator.h> #endif // We pick up concept_checks.h from stl_iterator_base.h. __STL_BEGIN_NAMESPACE // swap and iter_swap //交换两个迭代器a和b所指的内容 /*对外接口: template <class ForwardIterator1, class ForwardIterator2> void iter_swap (ForwardIterator1 a, ForwardIterator2 b); */ template <class _ForwardIter1, class _ForwardIter2, class _Tp> inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) { _Tp __tmp = *__a; *__a = *__b; *__b = __tmp; } template <class _ForwardIter1, class _ForwardIter2> inline void iter_swap(_ForwardIter1 __a, _ForwardIter2 __b) { __STL_REQUIRES(_ForwardIter1, _Mutable_ForwardIterator); __STL_REQUIRES(_ForwardIter2, _Mutable_ForwardIterator); __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter2>::value_type, typename iterator_traits<_ForwardIter1>::value_type); //调用上面的简单交换函数,萃取出a的型别 __iter_swap(__a, __b, __VALUE_TYPE(__a)); } //交换a和b的值 //这里采用引用传参 template <class _Tp> inline void swap(_Tp& __a, _Tp& __b) { __STL_REQUIRES(_Tp, _Assignable); _Tp __tmp = __a; __a = __b; __b = __tmp; } //-------------------------------------------------- // min and max /* 返回最小值:Returns the smallest of a and b. If both are equivalent, a is returned. default (1) :默认是采用operator<进行比较 template <class T> const T& min (const T& a, const T& b); custom (2) :用户自己提供的comp template <class T, class Compare> const T& min (const T& a, const T& b, Compare comp); */ /* 返回最大值:Returns the largest of a and b. If both are equivalent, a is returned. default (1) 默认是采用operator<进行比较 template <class T> const T& max (const T& a, const T& b); custom (2) 用户自己提供的comp template <class T, class Compare> const T& max (const T& a, const T& b, Compare comp); */ #if !defined(__BORLANDC__) || __BORLANDC__ >= 0x540 /* C++ Builder 4.0 */ #undef min #undef max template <class _Tp> inline const _Tp& min(const _Tp& __a, const _Tp& __b) { __STL_REQUIRES(_Tp, _LessThanComparable); return __b < __a ? __b : __a; } template <class _Tp> inline const _Tp& max(const _Tp& __a, const _Tp& __b) { __STL_REQUIRES(_Tp, _LessThanComparable); return __a < __b ? __b : __a; } #endif /* __BORLANDC__ */ template <class _Tp, class _Compare> inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) { return __comp(__b, __a) ? __b : __a; } template <class _Tp, class _Compare> inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) { return __comp(__a, __b) ? __b : __a; } //-------------------------------------------------- // copy // All of these auxiliary functions serve two purposes. (1) Replace // calls to copy with memmove whenever possible. (Memmove, not memcpy, // because the input and output ranges are permitted to overlap.) // (2) If we're using random access iterators, then write the loop as // a for loop with an explicit count. //若迭代器类型为输入迭代器,则调用此函数 template <class _InputIter, class _OutputIter, class _Distance> inline _OutputIter __copy(_InputIter __first, _InputIter __last, _OutputIter __result, input_iterator_tag, _Distance*) { for ( ; __first != __last; ++__result, ++__first)//只能一个一个的遍历输入区间 *__result = *__first;//一个一个的赋值operator= return __result; } //若迭代器的类型为随机访问迭代器,则调用此函数 template <class _RandomAccessIter, class _OutputIter, class _Distance> inline _OutputIter __copy(_RandomAccessIter __first, _RandomAccessIter __last, _OutputIter __result, random_access_iterator_tag, _Distance*) { for (_Distance __n = __last - __first; __n > 0; --__n) {//遍历输入区间 *__result = *__first;//对应赋值operator= ++__first; ++__result; } return __result; } //直接调用memmove复制,不需要其他操作 template <class _Tp> inline _Tp* __copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) { //memmove()是移动复制,注意:source和destination的内存空间可以重叠 /* 原型:void * memmove ( void * destination, const void * source, size_t num ); 功能: Copies the values of num bytes from the location pointed by source to the memory block pointed by destination. Copying takes place as if an intermediate buffer were used, allowing the destination and source to overlap. 注意:memmove有一个功能就是首先会把输入内容复制下来,所以允许输入区间与输出区间起始位置重叠 举例:example #include <stdio.h> #include <string.h> int main () { char str[] = "memmove can be very useful......"; //允许输出区间起始位置与输入区间重叠 //这是memmove的功能 memmove (str+20,str+15,11); puts (str); return 0; } Output: memmove can be very very useful. */ memmove(__result, __first, sizeof(_Tp) * (__last - __first)); return __result + (__last - __first); } #if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) //若不提供赋值操作assignment_operator,则调用此函数 template <class _InputIter, class _OutputIter> inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last, _OutputIter __result, __false_type) { //首先萃取出迭代器的类型 return __copy(__first, __last, __result, __ITERATOR_CATEGORY(__first), __DISTANCE_TYPE(__first)); } //若提供赋值操作assignment_operator,则调用此函数 template <class _InputIter, class _OutputIter> inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last, _OutputIter __result, __true_type) { //首先萃取出迭代器的类型 return __copy(__first, __last, __result, __ITERATOR_CATEGORY(__first), __DISTANCE_TYPE(__first)); } #ifndef __USLC__ //偏特化,参数为T* template <class _Tp> inline _Tp* __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result, __true_type) { return __copy_trivial(__first, __last, __result); } #endif /* __USLC__ */ //偏特化,参数为const T* //若提供赋值操作assignment_operator,则调用此函数 template <class _Tp> inline _Tp* __copy_aux2(const _Tp* __first, const _Tp* __last, _Tp* __result, __true_type) { return __copy_trivial(__first, __last, __result);//转而调用该函数 } //调用该函数 template <class _InputIter, class _OutputIter, class _Tp> inline _OutputIter __copy_aux(_InputIter __first, _InputIter __last, _OutputIter __result, _Tp*) { typedef typename __type_traits<_Tp>::has_trivial_assignment_operator _Trivial; //首先判断是否提供赋值操作assignment_operator return __copy_aux2(__first, __last, __result, _Trivial()); } /* 复制函数: template <class InputIterator, class OutputIterator> OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result); 功能:Copies the elements in the range [first,last) into the range beginning at result. 将输入区间[first,last)的内容复制到[result,result+(last-first))内 注意:result不能位于[first,last)内部,即输出端的起始位置不能位于输入区间内部; 但是允许输出区间的尾部与输入区间重叠,这与copy_backward相反 若两个区间不重叠则copy()和copy_backward()都可以使用 */ //完全泛化版,对外接口 template <class _InputIter, class _OutputIter> inline _OutputIter copy(_InputIter __first, _InputIter __last, _OutputIter __result) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); //首先萃取出first的类型,然后针对特定类型调用对应的函数__copy_aux() return __copy_aux(__first, __last, __result, __VALUE_TYPE(__first)); } // Hack for compilers that don't have partial ordering of function templates // but do have partial specialization of class templates. #elif defined(__STL_CLASS_PARTIAL_SPECIALIZATION) //完全泛化版本 template <class _InputIter, class _OutputIter, class _BoolType> struct __copy_dispatch { static _OutputIter copy(_InputIter __first, _InputIter __last, _OutputIter __result) { typedef typename iterator_traits<_InputIter>::iterator_category _Category; typedef typename iterator_traits<_InputIter>::difference_type _Distance; return __copy(__first, __last, __result, _Category(), (_Distance*) 0); } }; //偏特化1,两个参数都是T* template <class _Tp> struct __copy_dispatch<_Tp*, _Tp*, __true_type> { static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { return __copy_trivial(__first, __last, __result); } }; //偏特化2,第一个参数是const T*,第二个参数是T* template <class _Tp> struct __copy_dispatch<const _Tp*, _Tp*, __true_type> { static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { return __copy_trivial(__first, __last, __result); } }; //对外接口,完全泛化 template <class _InputIter, class _OutputIter> inline _OutputIter copy(_InputIter __first, _InputIter __last, _OutputIter __result) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); typedef typename iterator_traits<_InputIter>::value_type _Tp; typedef typename __type_traits<_Tp>::has_trivial_assignment_operator _Trivial; return __copy_dispatch<_InputIter, _OutputIter, _Trivial> ::copy(__first, __last, __result); } // Fallback for compilers with neither partial ordering nor partial // specialization. Define the faster version for the basic builtin // types. #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template <class _InputIter, class _OutputIter> inline _OutputIter copy(_InputIter __first, _InputIter __last, _OutputIter __result) { return __copy(__first, __last, __result, __ITERATOR_CATEGORY(__first), __DISTANCE_TYPE(__first)); } #define __SGI_STL_DECLARE_COPY_TRIVIAL(_Tp) \ inline _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { \ memmove(__result, __first, sizeof(_Tp) * (__last - __first)); \ return __result + (__last - __first); \ } __SGI_STL_DECLARE_COPY_TRIVIAL(char) __SGI_STL_DECLARE_COPY_TRIVIAL(signed char) __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned char) __SGI_STL_DECLARE_COPY_TRIVIAL(short) __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned short) __SGI_STL_DECLARE_COPY_TRIVIAL(int) __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned int) __SGI_STL_DECLARE_COPY_TRIVIAL(long) __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned long) #ifdef __STL_HAS_WCHAR_T __SGI_STL_DECLARE_COPY_TRIVIAL(wchar_t) #endif #ifdef _STL_LONG_LONG __SGI_STL_DECLARE_COPY_TRIVIAL(long long) __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned long long) #endif __SGI_STL_DECLARE_COPY_TRIVIAL(float) __SGI_STL_DECLARE_COPY_TRIVIAL(double) __SGI_STL_DECLARE_COPY_TRIVIAL(long double) #undef __SGI_STL_DECLARE_COPY_TRIVIAL #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ //-------------------------------------------------- // copy_backward /*原型 template <class BidirectionalIterator1, class BidirectionalIterator2> BidirectionalIterator2 copy_backward (BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result); */ //迭代器类型是双向迭代器的调用 template <class _BidirectionalIter1, class _BidirectionalIter2, class _Distance> inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first, _BidirectionalIter1 __last, _BidirectionalIter2 __result, bidirectional_iterator_tag, _Distance*) { while (__first != __last)//遍历输入区间 *--__result = *--__last;//逆向赋值operator= return __result; } //迭代器类型是随机访问迭代器的调用 template <class _RandomAccessIter, class _BidirectionalIter, class _Distance> inline _BidirectionalIter __copy_backward(_RandomAccessIter __first, _RandomAccessIter __last, _BidirectionalIter __result, random_access_iterator_tag, _Distance*) { for (_Distance __n = __last - __first; __n > 0; --__n)//遍历输入区间 *--__result = *--__last;//逆向赋值operator= return __result; } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION // This dispatch class is a workaround for compilers that do not // have partial ordering of function templates. All we're doing is // creating a specialization so that we can turn a call to copy_backward // into a memmove whenever possible. //完全泛化版 template <class _BidirectionalIter1, class _BidirectionalIter2, class _BoolType> struct __copy_backward_dispatch { typedef typename iterator_traits<_BidirectionalIter1>::iterator_category _Cat; typedef typename iterator_traits<_BidirectionalIter1>::difference_type _Distance; static _BidirectionalIter2 copy(_BidirectionalIter1 __first, _BidirectionalIter1 __last, _BidirectionalIter2 __result) { return __copy_backward(__first, __last, __result, _Cat(), (_Distance*) 0); } }; //偏特化,参数为原生指针T* template <class _Tp> struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type> { static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { const ptrdiff_t _Num = __last - __first; memmove(__result - _Num, __first, sizeof(_Tp) * _Num); return __result - _Num; } }; //偏特化,第一个参数为const T*,第二个参数为T* template <class _Tp> struct __copy_backward_dispatch<const _Tp*, _Tp*, __true_type> { static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { return __copy_backward_dispatch<_Tp*, _Tp*, __true_type> ::copy(__first, __last, __result); } }; //对外接口 template <class _BI1, class _BI2> inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { __STL_REQUIRES(_BI1, _BidirectionalIterator); __STL_REQUIRES(_BI2, _Mutable_BidirectionalIterator); __STL_CONVERTIBLE(typename iterator_traits<_BI1>::value_type, typename iterator_traits<_BI2>::value_type); typedef typename __type_traits<typename iterator_traits<_BI2>::value_type> ::has_trivial_assignment_operator _Trivial; return __copy_backward_dispatch<_BI1, _BI2, _Trivial> ::copy(__first, __last, __result); } #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template <class _BI1, class _BI2> inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { return __copy_backward(__first, __last, __result, __ITERATOR_CATEGORY(__first), __DISTANCE_TYPE(__first)); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ //-------------------------------------------------- // copy_n (not part of the C++ standard) /*原型 template <class InputIterator, class Size, class OutputIterator> OutputIterator copy_n (InputIterator first, Size n, OutputIterator result); 例子: #include <iostream> // std::cout #include <algorithm> // std::copy #include <vector> // std::vector int main () { int myints[]={10,20,30,40,50,60,70}; std::vector<int> myvector; myvector.resize(7); // allocate space for 7 elements std::copy_n ( myints, 7, myvector.begin() ); std::cout << "myvector contains:"; for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; } Output: myvector contains: 10 20 30 40 50 60 70 */ //C++11已经把这个列入标准库 //迭代器类型为输入迭代器 //从指定位置开始复制__count个与*first值相等的值 template <class _InputIter, class _Size, class _OutputIter> pair<_InputIter, _OutputIter> __copy_n(_InputIter __first, _Size __count, _OutputIter __result, input_iterator_tag) { for ( ; __count > 0; --__count) {//若个数不小于0,则进行操作 *__result = *__first;//赋值operator= ++__first; ++__result; } return pair<_InputIter, _OutputIter>(__first, __result); } //迭代器为随机访问迭代器 template <class _RAIter, class _Size, class _OutputIter> inline pair<_RAIter, _OutputIter> __copy_n(_RAIter __first, _Size __count, _OutputIter __result, random_access_iterator_tag) { _RAIter __last = __first + __count; return pair<_RAIter, _OutputIter>(__last, copy(__first, __last, __result)); } //萃取迭代器的类型 template <class _InputIter, class _Size, class _OutputIter> inline pair<_InputIter, _OutputIter> __copy_n(_InputIter __first, _Size __count, _OutputIter __result) { return __copy_n(__first, __count, __result, __ITERATOR_CATEGORY(__first)); } //对外接口,完全泛化 template <class _InputIter, class _Size, class _OutputIter> inline pair<_InputIter, _OutputIter> copy_n(_InputIter __first, _Size __count, _OutputIter __result) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); return __copy_n(__first, __count, __result); } //-------------------------------------------------- // fill and fill_n /* 填充值:Assigns val to all the elements in the range [first,last). template <class ForwardIterator, class T> void fill (ForwardIterator first, ForwardIterator last, const T& val); */ //把区间[first,last)的值都填充为value template <class _ForwardIter, class _Tp> void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); for ( ; __first != __last; ++__first)//遍历区间 *__first = __value;//当前位置赋予值value } /* 在指定位置连续填充n个值:Assigns val to the first n elements of the sequence pointed by first. template <class OutputIterator, class Size, class T> void fill_n (OutputIterator first, Size n, const T& val); */ //从first开始连续填充n个value值 template <class _OutputIter, class _Size, class _Tp> _OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __value) { __STL_REQUIRES(_OutputIter, _OutputIterator); for ( ; __n > 0; --__n, ++__first)//从first开始遍历n个位置 *__first = __value;//当前位置赋予值value return __first; } // Specialization: for one-byte types we can use memset. inline void fill(unsigned char* __first, unsigned char* __last, const unsigned char& __c) { unsigned char __tmp = __c; //按字节填充 //Sets the first num bytes of the block of memory pointed by ptr to the specified value (interpreted as an unsigned char). memset(__first, __tmp, __last - __first); } inline void fill(signed char* __first, signed char* __last, const signed char& __c) { signed char __tmp = __c; memset(__first, static_cast<unsigned char>(__tmp), __last - __first); } inline void fill(char* __first, char* __last, const char& __c) { char __tmp = __c; memset(__first, static_cast<unsigned char>(__tmp), __last - __first); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template <class _Size> inline unsigned char* fill_n(unsigned char* __first, _Size __n, const unsigned char& __c) { fill(__first, __first + __n, __c); return __first + __n; } template <class _Size> inline signed char* fill_n(char* __first, _Size __n, const signed char& __c) { fill(__first, __first + __n, __c); return __first + __n; } template <class _Size> inline char* fill_n(char* __first, _Size __n, const char& __c) { fill(__first, __first + __n, __c); return __first + __n; } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ //-------------------------------------------------- // equal and mismatch /* 判断两个区间的第一个不匹配点,返回一个由两个迭代器组成的pair, 其中第一个迭代器指向第一个区间的不匹配点,第二个迭代器指向第二个区间的不匹配点 如果都匹配,返回的是指向两个区间的last迭代器。 quality (1) :采用默认operator==比较 template <class InputIterator1, class InputIterator2> pair<InputIterator1, InputIterator2> mismatch (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); predicate (2):指定比较规则pred template <class InputIterator1, class InputIterator2, class BinaryPredicate> pair<InputIterator1, InputIterator2> mismatch (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); */ //版本一:采用默认比较规则operator== template <class _InputIter1, class _InputIter2> pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _EqualityComparable); __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type, _EqualityComparable); //遍历区间,寻找不匹配点 //注意:第一个区间的元素不能比第二个区间元素多 while (__first1 != __last1 && *__first1 == *__first2) { ++__first1; ++__first2; } return pair<_InputIter1, _InputIter2>(__first1, __first2); } //版本二:自定义比较规则 template <class _InputIter1, class _InputIter2, class _BinaryPredicate> pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); //遍历区间,寻找不匹配点 while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) { ++__first1; ++__first2; } return pair<_InputIter1, _InputIter2>(__first1, __first2); } /* Compares the elements in the range [first1,last1) with those in the range beginning at first2, and returns true if all of the elements in both ranges match. 比较两个序列指定范围大小:如果两个序列在[first,last)区间相等,则返回true 如果第二个序列的元素比较多,多出来的元素不予考虑; equality (1):默认采用operator==比较 template <class InputIterator1, class InputIterator2> bool equal (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); predicate (2):用户可指定比较规则 template <class InputIterator1, class InputIterator2, class BinaryPredicate> bool equal (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); */ //版本一‘:采用默认比较规则operator== template <class _InputIter1, class _InputIter2> inline bool equal(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _EqualityComparable); __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type, _EqualityComparable); //遍历区间 for ( ; __first1 != __last1; ++__first1, ++__first2) if (*__first1 != *__first2) return false;//若对应元素不相等,返回FALSE return true;//至此全部相等 } //版本二:采用用户自定义的比较规则 template <class _InputIter1, class _InputIter2, class _BinaryPredicate> inline bool equal(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); //遍历区间 for ( ; __first1 != __last1; ++__first1, ++__first2) if (!__binary_pred(*__first1, *__first2)) return false;//若对应元素不符合规则,返回FALSE return true;//至此全部符合 } //-------------------------------------------------- // lexicographical_compare and lexicographical_compare_3way. // (the latter is not part of the C++ standard.) /*功能:Returns true if the range [first1,last1) compares lexicographically less than the range [first2,last2). default (1) template <class InputIterator1, class InputIterator2> bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); custom (2) template <class InputIterator1, class InputIterator2, class Compare> bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); */ /* 对两个序列[first1,last1)和[first2,last2)进行比较,比较操作针对两个序列对应位置上的元素进行; 并持续到: (1)某一组对应元素不相等 (2)同时达到last1和last2(即两个序列大小相等) (3)达到last1或last2(两个序列大小不相等) */ //版本一:默认比较操作为less template <class _InputIter1, class _InputIter2> bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type, _LessThanComparable); //以下任何一个序列到达尾端,则结束,否则两序列就相应元素进行比较 for ( ; __first1 != __last1 && __first2 != __last2 ; ++__first1, ++__first2) { if (*__first1 < *__first2)//若第一序列对应元素小于第二序列对应元素 return true;//返回TRUE if (*__first2 < *__first1)//若第二序列对应元素小于第一序列对应元素 return false;//返回FALSE //若两序列对应元素相等,则继续进入下一组对应元素比较 } //如果第一序列已到达尾端,而第二序列还存在元素,则第一序列小于第二序列 return __first1 == __last1 && __first2 != __last2; } //版本二:用户可自行指定比较规则 template <class _InputIter1, class _InputIter2, class _Compare> bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); //以下任何一个序列到达尾端,则结束,否则两序列就相应元素进行比较 for ( ; __first1 != __last1 && __first2 != __last2 ; ++__first1, ++__first2) { if (__comp(*__first1, *__first2))//若第一序列对应元素符合规则于第二序列对应元素 return true;//返回TRUE if (__comp(*__first2, *__first1))//若第二序列对应元素符合规则于第一序列对应元素 return false;//返回FALSE //若两序列对应元素相等,则继续进入下一组对应元素比较 } //如果第一序列已到达尾端,而第二序列还存在元素,则第一序列符合规则于第二序列 return __first1 == __last1 && __first2 != __last2; } //这是针对const unsigned cahr*的特化版本 inline bool lexicographical_compare(const unsigned char* __first1, const unsigned char* __last1, const unsigned char* __first2, const unsigned char* __last2) { const size_t __len1 = __last1 - __first1;//第一序列长度 const size_t __len2 = __last2 - __first2;//第二序列长度 //先比较长度相同的一小段 /* memcmp函数的描述: 原型:int memcmp ( const void * ptr1, const void * ptr2, size_t num ); Compares the first num bytes of the block of memory pointed by ptr1 to the first num bytes pointed by ptr2, returning zero if they all match or a value different from zero representing which is greater if they do not. */ const int __result = memcmp(__first1, __first2, min(__len1, __len2)); //根据返回结果result的值与0比较进行判断 //result<0:第一序列小于第二序列 //result>0:第一序列大于第二序列 //result=0:两个序列相等 return __result != 0 ? __result < 0 : __len1 < __len2; } //针对const char*的特化版本 inline bool lexicographical_compare(const char* __first1, const char* __last1, const char* __first2, const char* __last2) { #if CHAR_MAX == SCHAR_MAX return lexicographical_compare((const signed char*) __first1, (const signed char*) __last1, (const signed char*) __first2, (const signed char*) __last2); #else /* CHAR_MAX == SCHAR_MAX */ return lexicographical_compare((const unsigned char*) __first1, (const unsigned char*) __last1, (const unsigned char*) __first2, (const unsigned char*) __last2); #endif /* CHAR_MAX == SCHAR_MAX */ } //类似于strcmp()的泛化版本 //默认比较操作是less template <class _InputIter1, class _InputIter2> int __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2) { //以下任何一个序列到达尾端,则结束,否则两序列就相应元素进行比较 while (__first1 != __last1 && __first2 != __last2) { if (*__first1 < *__first2)//若第一个元素小于第二序列对应的元素 return -1;//则返回负值-1 if (*__first2 < *__first1)//若第二序列元素小于第一序列对应元素 return 1;//则返回正值1 //继续遍历 //若两序列对应元素相等,则继续进入下一组对应元素比较 ++__first1; ++__first2; } //若第二序列已到达尾端 if (__first2 == __last2) { //若第一序列也同时到达尾端,表示两序列相等,则返回0; //若第一序列没到达尾端,则表示第一序列大于第二序列 //则返回正值1 return !(__first1 == __last1); } else {//若第一序列已到达尾端,而第二序列还没到达尾端 //则返回负值-1 return -1; } } //以下是针对const unsigned char* inline int __lexicographical_compare_3way(const unsigned char* __first1, const unsigned char* __last1, const unsigned char* __first2, const unsigned char* __last2) { const ptrdiff_t __len1 = __last1 - __first1; const ptrdiff_t __len2 = __last2 - __first2; const int __result = memcmp(__first1, __first2, min(__len1, __len2)); return __result != 0 ? __result : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); } //这是const char*特化版 inline int __lexicographical_compare_3way(const char* __first1, const char* __last1, const char* __first2, const char* __last2) { #if CHAR_MAX == SCHAR_MAX return __lexicographical_compare_3way( (const signed char*) __first1, (const signed char*) __last1, (const signed char*) __first2, (const signed char*) __last2); #else return __lexicographical_compare_3way((const unsigned char*) __first1, (const unsigned char*) __last1, (const unsigned char*) __first2, (const unsigned char*) __last2); #endif } //针对上面函数的封装 template <class _InputIter1, class _InputIter2> int lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type, _LessThanComparable); return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_ALGOBASE_H */ // Local Variables: // mode:C++ // End: ~~~ 参考资料: 《STL源码剖析》侯捷
';

stl_relops.h学习

最后更新于:2022-04-01 15:51:20

### 前言   这个文件提供了操作符的重载,但是没有提供operator==和operator<的重载,用户要使用这些操作符时,必须自己重载operator==和operator<操作符,因为该文件的重载操作符都是基于这两种操作符。本文件出自SGI STL中的<stl_relops.h>。 ### relops源码 ~~~ // 这里提供比较运算符的重载, 任何全局的比较运算符如果需要重载 // 只需要自己提供operator <和==即可 #ifndef __SGI_STL_INTERNAL_RELOPS #define __SGI_STL_INTERNAL_RELOPS __STL_BEGIN_RELOPS_NAMESPACE template <class _Tp> inline bool operator!=(const _Tp& __x, const _Tp& __y) { return !(__x == __y); } template <class _Tp> inline bool operator>(const _Tp& __x, const _Tp& __y) { return __y < __x; } template <class _Tp> inline bool operator<=(const _Tp& __x, const _Tp& __y) { return !(__y < __x); } template <class _Tp> inline bool operator>=(const _Tp& __x, const _Tp& __y) { return !(__x < __y); } __STL_END_RELOPS_NAMESPACE #endif /* __SGI_STL_INTERNAL_RELOPS */ // Local Variables: // mode:C++ // End: ~~~
';

数值算法stl_numeric.h

最后更新于:2022-04-01 15:51:18

### 前言   在STL中,算法是独立于特定的数据结构,称为泛型算法。本节介绍的数值算法是在源码SGI STL中的<stl_numeric.h>文件,具体功能详见下面的源码剖析,在源码剖析的时候,针对每个元素都给出了使用例子,这样可以增加对其理解。 ### numeric数值算法源码剖析 ~~~ #ifndef __SGI_STL_INTERNAL_NUMERIC_H #define __SGI_STL_INTERNAL_NUMERIC_H __STL_BEGIN_NAMESPACE /* sum (1) :The default operation is to add the elements up; 这个版本的默认操作时累加; template <class InputIterator, class T> T accumulate (InputIterator first, InputIterator last, T init); custom (2): a different operation can be specified as binary_op; 这个版本的操作可以是用户通过binary_op自行指定;指定函数在<stl_function.h>定义,也可自己定义 template <class InputIterator, class T, class BinaryOperation> T accumulate (InputIterator first, InputIterator last, T init, BinaryOperation binary_op); */ //第一个版本:默认操作是累加 //计算[first,last)区间元素与init的和 //返回一个副本 template <class _InputIterator, class _Tp> _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) { __STL_REQUIRES(_InputIterator, _InputIterator); for ( ; __first != __last; ++__first)//遍历指定范围元素 __init = __init + *__first;//将每个元素累加到初始值init上 return __init; } //第二个版本:用户可自行指定二元操作函数 template <class _InputIterator, class _Tp, class _BinaryOperation> _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op) { __STL_REQUIRES(_InputIterator, _InputIterator); for ( ; __first != __last; ++__first)//遍历指定范围元素 __init = __binary_op(__init, *__first);//对每个元素执行二元操作 return __init; } //下面举例子: /*accumulate example: #include <iostream> // std::cout #include <functional> // std::minus #include <numeric> // std::accumulate int myfunction (int x, int y) {return x+2*y;} struct myclass { int operator()(int x, int y) {return x+3*y;} } myobject; int main () { int init = 100; int numbers[] = {10,20,30}; std::cout << "using default accumulate: "; std::cout << std::accumulate(numbers,numbers+3,init); std::cout << '\n'; std::cout << "using functional's minus: "; std::cout << std::accumulate (numbers, numbers+3, init, std::minus<int>()); std::cout << '\n'; std::cout << "using custom function: "; std::cout << std::accumulate (numbers, numbers+3, init, myfunction); std::cout << '\n'; std::cout << "using custom object: "; std::cout << std::accumulate (numbers, numbers+3, init, myobject); std::cout << '\n'; return 0; } Output: using default accumulate: 160 using functional's minus: 40 using custom function: 220 using custom object: 280 */ /*默认操作是把内积(相乘)的值与初始值init相加 用户可以自行指定操作类型 sum/multiply (1) template <class InputIterator1, class InputIterator2, class T> T inner_product (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); custom (2) template <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2> T inner_product (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); */ //描述:The two default operations (to add up the result of multiplying the pairs) //may be overridden by the arguments binary_op1 and binary_op2. //功能:Returns the result of accumulating init with the inner products of the pairs //formed by the elements of two ranges starting at first1 and first2. //版本一:使用默认操作 template <class _InputIterator1, class _InputIterator2, class _Tp> _Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init) { __STL_REQUIRES(_InputIterator2, _InputIterator); __STL_REQUIRES(_InputIterator2, _InputIterator); //以第一个序列的元素个数为据,将两个序列都走一遍 for ( ; __first1 != __last1; ++__first1, ++__first2)、 __init = __init + (*__first1 * *__first2);//执行两个序列的内积与初始值init相加 return __init; } //版本二:用户可自行指定二元操作函数 template <class _InputIterator1, class _InputIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2> _Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { __STL_REQUIRES(_InputIterator2, _InputIterator); __STL_REQUIRES(_InputIterator2, _InputIterator); //以第一个序列的元素个数为据,将两个序列都走一遍 for ( ; __first1 != __last1; ++__first1, ++__first2) //首先指定__binary_op2操作,再指定__binary_op1操作 __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); return __init; } //下面举例子: /*inner_product example: #include <iostream> // std::cout #include <functional> // std::minus, std::divides #include <numeric> // std::inner_product int myaccumulator (int x, int y) {return x-y;} int myproduct (int x, int y) {return x+y;} int main () { int init = 10; int series1[] = {10,20,30}; int series2[] = {1,2,3}; std::cout << "using default inner_product: "; std::cout << std::inner_product(series1,series1+3,series2,init); std::cout << '\n'; std::cout << "using functional operations: "; std::cout << std::inner_product(series1,series1+3,series2,init, std::minus<int>(),std::divides<int>()); std::cout << '\n'; std::cout << "using custom functions: "; std::cout << std::inner_product(series1,series1+3,series2,init, myaccumulator,myproduct); std::cout << '\n'; return 0; } Output: using default inner_product: 150 using functional operations: -20 using custom functions: -56 */ //局部求和 /*功能与描述: Assigns to every element in the range starting at result the partial sum of the corresponding elements in the range [first,last). If x represents an element in [first,last) and y represents an element in result, the ys can be calculated as: y0 = x0 y1 = x0 + x1 y2 = x0 + x1 + x2 y3 = x0 + x1 + x2 + x3 y4 = x0 + x1 + x2 + x3 + x4 ... ... ... */ /*版本一:默认操作是:The default operation is to add the elements up; sum (1) template <class InputIterator, class OutputIterator> OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result); 版本二:用户可以自行指定二元操作:operation can be specified as binary_op instead. custom (2) template <class InputIterator, class OutputIterator, class BinaryOperation> OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); */ //版本一:默认操作函数 template <class _InputIterator, class _OutputIterator, class _Tp> _OutputIterator __partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp*) { _Tp __value = *__first; while (++__first != __last) {//遍历区间元素 __value = __value + *__first;//区间前n个元素的总和 *++__result = __value;//把元素赋给输出端 } return ++__result; } template <class _InputIterator, class _OutputIterator> _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { __STL_REQUIRES(_InputIterator, _InputIterator); __STL_REQUIRES(_OutputIterator, _OutputIterator); if (__first == __last) return __result;//若为空 *__result = *__first;//初始值 //调用上面的函数,萃取出first的类型方便上面函数使用 return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first)); } //版本二:用户指定二元操作函数 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOperation> _OutputIterator __partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp*, _BinaryOperation __binary_op) { _Tp __value = *__first; while (++__first != __last) {//遍历区间元素 __value = __binary_op(__value, *__first);//区间前n个元素的__binary_op *++__result = __value;//把元素赋给输出端 } return ++__result; } template <class _InputIterator, class _OutputIterator, class _BinaryOperation> _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOperation __binary_op) { __STL_REQUIRES(_InputIterator, _InputIterator); __STL_REQUIRES(_OutputIterator, _OutputIterator); if (__first == __last) return __result; *__result = *__first; //调用上面的函数,萃取出first的类型方便上面函数使用 return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first), __binary_op); } //下面举例: /*partial_sum example: #include <iostream> // std::cout #include <functional> // std::multiplies #include <numeric> // std::partial_sum int myop (int x, int y) {return x+y+1;} int main () { int val[] = {1,2,3,4,5}; int result[5]; std::partial_sum (val, val+5, result); std::cout << "using default partial_sum: "; for (int i=0; i<5; i++) std::cout << result[i] << ' '; std::cout << '\n'; std::partial_sum (val, val+5, result, std::multiplies<int>()); std::cout << "using functional operation multiplies: "; for (int i=0; i<5; i++) std::cout << result[i] << ' '; std::cout << '\n'; std::partial_sum (val, val+5, result, myop); std::cout << "using custom function: "; for (int i=0; i<5; i++) std::cout << result[i] << ' '; std::cout << '\n'; return 0; } Output: using default partial_sum: 1 3 6 10 15 using functional operation multiplies: 1 2 6 24 120 using custom function: 1 4 8 13 19 */ /*功能与描述: Assigns to every element in the range starting at result the difference between its corresponding element in the range [first,last) and the one preceding it (except for *result, which is assigned *first). If x represents an element in [first,last) and y represents an element in result, the ys can be calculated as: y0 = x0 y1 = x1 - x0 y2 = x2 - x1 y3 = x3 - x2 y4 = x4 - x3 ... ... ... The default operation is to calculate the difference, but some other operation can be specified as binary_op instead. */ /* difference (1) template <class InputIterator, class OutputIterator> OutputIterator adjacent_difference (InputIterator first, InputIterator last, OutputIterator result); custom (2) template <class InputIterator, class OutputIterator, class BinaryOperation> OutputIterator adjacent_difference ( InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op ); */ //版本一:默认操作函数 template <class _InputIterator, class _OutputIterator, class _Tp> _OutputIterator __adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp*) { _Tp __value = *__first; while (++__first != __last) {//遍历区间 _Tp __tmp = *__first;//初始化tmp *++__result = __tmp - __value;//计算相邻两元素的差额(后-前),并赋给输出端 __value = __tmp;//更新当前值 } return ++__result; } template <class _InputIterator, class _OutputIterator> _OutputIterator adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { __STL_REQUIRES(_InputIterator, _InputIterator); __STL_REQUIRES(_OutputIterator, _OutputIterator); if (__first == __last) return __result;//若为空直接返回 *__result = *__first;//初始值 //调用上面的函数__adjacent_difference() return __adjacent_difference(__first, __last, __result, __VALUE_TYPE(__first)); } //版本二:可指定操作函数 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOperation> _OutputIterator __adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp*, _BinaryOperation __binary_op) { _Tp __value = *__first; while (++__first != __last) {//遍历区间 _Tp __tmp = *__first;//初始化tmp *++__result = __binary_op(__tmp, __value);//计算相邻两元素的操作,并赋给输出端 __value = __tmp;//更新当前值 } return ++__result; } template <class _InputIterator, class _OutputIterator, class _BinaryOperation> _OutputIterator adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOperation __binary_op) { __STL_REQUIRES(_InputIterator, _InputIterator); __STL_REQUIRES(_OutputIterator, _OutputIterator); if (__first == __last) return __result;//若为空直接返回 *__result = *__first;//初始值 //调用上面的函数__adjacent_difference() return __adjacent_difference(__first, __last, __result, __VALUE_TYPE(__first), __binary_op); } //下面举例子: /*adjacent_difference example: #include <iostream> // std::cout #include <functional> // std::multiplies #include <numeric> // std::adjacent_difference int myop (int x, int y) {return x+y;} int main () { int val[] = {1,2,3,5,9,11,12}; int result[7]; std::adjacent_difference (val, val+7, result); std::cout << "using default adjacent_difference: "; for (int i=0; i<7; i++) std::cout << result[i] << ' '; std::cout << '\n'; std::adjacent_difference (val, val+7, result, std::multiplies<int>()); std::cout << "using functional operation multiplies: "; for (int i=0; i<7; i++) std::cout << result[i] << ' '; std::cout << '\n'; std::adjacent_difference (val, val+7, result, myop); std::cout << "using custom function: "; for (int i=0; i<7; i++) std::cout << result[i] << ' '; std::cout << '\n'; return 0; } output: using default adjacent_difference: 1 1 1 2 4 2 1 using functional operation multiplies: 1 2 6 15 45 99 132 using custom function: 1 3 5 8 14 20 23 */ // Returns __x **__n, where __n >= 0. _Note that "multiplication" // is required to be associative, but not necessarily commutative. //power为SGI专属,并不在STL标准之列,它用来计算某数的n幂次方。 // 版本一,幂次方。如果指定为乘法运算,则当n >= 0 时传回 x^n。 // 注意,"multiplication" 必须满足结合律(associative), // 但不需满足交换律(commutative)。 template <class _Tp, class _Integer, class _MonoidOperation> _Tp __power(_Tp __x, _Integer __n, _MonoidOperation __opr) { if (__n == 0) return identity_element(__opr); else { while ((__n & 1) == 0) { __n >>= 1; __x = __opr(__x, __x); } _Tp __result = __x; __n >>= 1; while (__n != 0) { __x = __opr(__x, __x); if ((__n & 1) != 0) __result = __opr(__result, __x); __n >>= 1; } return __result; } } //版本二:以 multiplies<_Tp>()操作调用版本一 template <class _Tp, class _Integer> inline _Tp __power(_Tp __x, _Integer __n) { return __power(__x, __n, multiplies<_Tp>()); } // Alias for the internal name __power. Note that power is an extension, // not part of the C++ standard. //对上面函数的封装 template <class _Tp, class _Integer, class _MonoidOperation> inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __opr) { return __power(__x, __n, __opr); } template <class _Tp, class _Integer> inline _Tp power(_Tp __x, _Integer __n) { return __power(__x, __n); } // iota is not part of the C++ standard. It is an extension. //C++11已经把这个列为STL的标准 //设定某个区间的内容,使其每个元素从指定值value开始,呈现递增 //在 [first,last) 范围内內填入value, value+1, value+2... template <class _ForwardIter, class _Tp> void iota(_ForwardIter __first, _ForwardIter __last, _Tp __value) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); while (__first != __last) *__first++ = __value++; } //举例子: /*iota example #include <iostream> // std::cout #include <numeric> // std::iota int main () { int numbers[10]; std::iota (numbers,numbers+10,100); std::cout << "numbers:"; for (int& i:numbers) std::cout << ' ' << i; std::cout << '\n'; return 0; } output: numbers: 100 101 102 103 104 105 106 107 108 109 */ __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_NUMERIC_H */ // Local Variables: // mode:C++ // End: ~~~ 参考资料: 《STL源码剖析》侯捷
';

关联容器之hash_multimap

最后更新于:2022-04-01 15:51:16

### 前言      hash_multimap和hash_map的区别就像multimap与map的区别一样,hash_multimap的底层机制是基于hash table,它可以存在重复的键值,所以插入函数使用insert_equal(),hash_multimap和hash_map一样,容器的内容不自动排序。由于hash_multimap和hash_map的源码剖析是一样的,这里就不对hash_multimap进行剖析,可以参照《[关联容器之](http://blog.csdn.net/chenhanzhun/article/details/39609093)[hash_map](http://blog.csdn.net/chenhanzhun/article/details/39609093)》。本文源码出自SGI STL的<stl_hash_map.h>文件。 ### hash_multimap源码 ~~~ // Forward declaration of equality operator; needed for friend declaration. //hash_multimap与hash_map的差别就是插入函数,前者的插入函数是采用底层机制hash table的insert_equal() //后者则采用insert_unique() //其他的功能都和hash_map类似 //hash_multimap允许key重复 //这里就不再进行注释了,可以参考hash_map的解析 template <class _Key, class _Tp, class _HashFcn __STL_DEPENDENT_DEFAULT_TMPL(hash<_Key>), class _EqualKey __STL_DEPENDENT_DEFAULT_TMPL(equal_to<_Key>), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > class hash_multimap; template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> inline bool operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2); template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc> class hash_multimap { // requirements: __STL_CLASS_REQUIRES(_Key, _Assignable); __STL_CLASS_REQUIRES(_Tp, _Assignable); __STL_CLASS_UNARY_FUNCTION_CHECK(_HashFcn, size_t, _Key); __STL_CLASS_BINARY_FUNCTION_CHECK(_EqualKey, bool, _Key, _Key); private: typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFcn, _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef _Tp data_type; typedef _Tp mapped_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Ht::pointer pointer; typedef typename _Ht::const_pointer const_pointer; typedef typename _Ht::reference reference; typedef typename _Ht::const_reference const_reference; typedef typename _Ht::iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } public: hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_multimap(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_multimap(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} #ifdef __STL_MEMBER_TEMPLATES template <class _InputIterator> hash_multimap(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template <class _InputIterator> hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template <class _InputIterator> hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template <class _InputIterator> hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_equal(__f, __l); } #else hash_multimap(const value_type* __f, const value_type* __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multimap(const value_type* __f, const value_type* __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multimap(const value_type* __f, const value_type* __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multimap(const value_type* __f, const value_type* __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_equal(__f, __l); } hash_multimap(const_iterator __f, const_iterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multimap(const_iterator __f, const_iterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multimap(const_iterator __f, const_iterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multimap(const_iterator __f, const_iterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_equal(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ public: size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); } #ifdef __STL_MEMBER_TEMPLATES template <class _K1, class _T1, class _HF, class _EqK, class _Al> friend bool operator== (const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&, const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&); #else /* __STL_MEMBER_TEMPLATES */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const hash_multimap&,const hash_multimap&); #endif /* __STL_MEMBER_TEMPLATES */ iterator begin() { return _M_ht.begin(); } iterator end() { return _M_ht.end(); } const_iterator begin() const { return _M_ht.begin(); } const_iterator end() const { return _M_ht.end(); } public: iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } #ifdef __STL_MEMBER_TEMPLATES template <class _InputIterator> void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } #else void insert(const value_type* __f, const value_type* __l) { _M_ht.insert_equal(__f,__l); } void insert(const_iterator __f, const_iterator __l) { _M_ht.insert_equal(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ iterator insert_noresize(const value_type& __obj) { return _M_ht.insert_equal_noresize(__obj); } iterator find(const key_type& __key) { return _M_ht.find(__key); } const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair<iterator, iterator> equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } pair<const_iterator, const_iterator> equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) {return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } public: void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> inline bool operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) { return __hm1._M_ht == __hm2._M_ht; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> inline bool operator!=(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) { return !(__hm1 == __hm2); } template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> inline void swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { __hm1.swap(__hm2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // Specialization of insert_iterator so that it will work for hash_map // and hash_multimap. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> class insert_iterator<hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> > { protected: typedef hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container; _Container* container; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> class insert_iterator<hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> > { protected: typedef hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container; _Container* container; typename _Container::iterator iter; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_HASH_MAP_H */ // Local Variables: // mode:C++ // End: ~~~ 参考资料: 《STL源码剖析》侯捷
';

关联容器之hash_map

最后更新于:2022-04-01 15:51:13

### 前言   由于前文介绍的《[散列表](http://blog.csdn.net/chenhanzhun/article/details/39578597)[hashtable](http://blog.csdn.net/chenhanzhun/article/details/39578597)》中,可以知道hash table在查找、删除和插入节点是常数时间,优于RB-Tree红黑树,所以在SGI STL中提供了底层机制基于hash table的hash_map容器,hash_map和map类似,但是不同点是hash_map容器中的元素是没有排序的,因为hash table没有提供排序功能。本文源码出自SGI STL的<stl_hash_map.h>文件。         ### hash_map源码剖析 ~~~ #ifndef __SGI_STL_INTERNAL_HASH_MAP_H #define __SGI_STL_INTERNAL_HASH_MAP_H #include <concept_checks.h> __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif //hash_map的底层是基于hash table的,hash table没有提供排序,所以hash_map容器里面的内容是没排序的 // Forward declaration of equality operator; needed for friend declaration. template <class _Key, class _Tp, class _HashFcn __STL_DEPENDENT_DEFAULT_TMPL(hash<_Key>), class _EqualKey __STL_DEPENDENT_DEFAULT_TMPL(equal_to<_Key>), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > class hash_map; template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> inline bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&, const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&); template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc> class hash_map { // requirements: __STL_CLASS_REQUIRES(_Key, _Assignable); __STL_CLASS_REQUIRES(_Tp, _Assignable); __STL_CLASS_UNARY_FUNCTION_CHECK(_HashFcn, size_t, _Key); __STL_CLASS_BINARY_FUNCTION_CHECK(_EqualKey, bool, _Key, _Key); private: //_Select1st<>取出键值key,_Select1st<>定义在<stl_function.h> /* template <class _Arg, class _Result> struct unary_function { typedef _Arg argument_type; typedef _Result result_type; }; template <class _Pair> struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { const typename _Pair::first_type& operator()(const _Pair& __x) const { return __x.first; } }; */ typedef hashtable<pair<const _Key,_Tp>,_Key,_HashFcn, _Select1st<pair<const _Key,_Tp> >,_EqualKey,_Alloc> _Ht; _Ht _M_ht;//底层机制以hash table完成 public: //以下的内嵌类型均来是hash table typedef typename _Ht::key_type key_type; typedef _Tp data_type; typedef _Tp mapped_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Ht::pointer pointer; typedef typename _Ht::const_pointer const_pointer; typedef typename _Ht::reference reference; typedef typename _Ht::const_reference const_reference; typedef typename _Ht::iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; //返回hash相关函数 hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } public: //构造函数 //缺省情况使用大小为100,但是实际分配的空间大小为不小于100的最小素数 //只是空的hash_map,不存储元素节点 hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} //指定大小n的hash_map表 explicit hash_map(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} //指定大小为n,且指定hash函数的hash_map hash_map(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} //指定大小为n,且指定hash函数和键值比较函数的hash_map hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} #ifdef __STL_MEMBER_TEMPLATES //以下hash_map的插入操作使用hash table的insert_unique插入 //不允许有相同的键值插入 //用某个范围的元素初始化hash_map对象 //相当于把某个范围[f,l)插入到空的hash_map template <class _InputIterator> hash_map(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); }//调用hash table的插入函数 template <class _InputIterator> hash_map(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template <class _InputIterator> hash_map(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template <class _InputIterator> hash_map(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_unique(__f, __l); } #else hash_map(const value_type* __f, const value_type* __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_map(const value_type* __f, const value_type* __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_map(const value_type* __f, const value_type* __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_map(const value_type* __f, const value_type* __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_unique(__f, __l); } hash_map(const_iterator __f, const_iterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_map(const_iterator __f, const_iterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_map(const_iterator __f, const_iterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_map(const_iterator __f, const_iterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_unique(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ public: //以下的函数操作只是调用hash table的成员函数 //返回 hash_map 容器中元素的个数. size_type size() const { return _M_ht.size(); } //返回hash_map容器最大存储元素的个数. size_type max_size() const { return _M_ht.max_size(); } //Returns a bool value indicating whether the hash_map container is empty, //i.e. whether its size is 0. bool empty() const { return _M_ht.empty(); } //交换两个存储相同元素类型的hash_map容器内容,但是hash_map容器大小可以不同 void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); } #ifdef __STL_MEMBER_TEMPLATES template <class _K1, class _T1, class _HF, class _EqK, class _Al> friend bool operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&, const hash_map<_K1, _T1, _HF, _EqK, _Al>&); #else /* __STL_MEMBER_TEMPLATES */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const hash_map&, const hash_map&); #endif /* __STL_MEMBER_TEMPLATES */ iterator begin() { return _M_ht.begin(); } iterator end() { return _M_ht.end(); } const_iterator begin() const { return _M_ht.begin(); } const_iterator end() const { return _M_ht.end(); } public: //插入元素 /* (1) pair<iterator,bool> insert ( const value_type& val ); (2) template <class InputIterator> void insert ( InputIterator first, InputIterator last ); */ //不允许有重复的键值 //返回pair第二个参数second若为true则插入成功 pair<iterator,bool> insert(const value_type& __obj) { return _M_ht.insert_unique(__obj); }//调用hash table的insert_unique()函数 #ifdef __STL_MEMBER_TEMPLATES template <class _InputIterator> void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f,__l); } #else void insert(const value_type* __f, const value_type* __l) { _M_ht.insert_unique(__f,__l); } void insert(const_iterator __f, const_iterator __l) { _M_ht.insert_unique(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ pair<iterator,bool> insert_noresize(const value_type& __obj) { return _M_ht.insert_unique_noresize(__obj); } //Searches the container for an element with k as key and returns an iterator to it if found, //otherwise it returns an iterator to hash_map::end iterator find(const key_type& __key) { return _M_ht.find(__key); } const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } //If k matches the key of an element in the container, the function returns a reference to its mapped value. _Tp& operator[](const key_type& __key) { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; } //Searches the container for elements whose key is k and returns the number of elements found. //由于不存在重复的键值,所以返回的个数最多为1个 size_type count(const key_type& __key) const { return _M_ht.count(__key); } //Returns the bounds of a range that includes all the elements in the container with a key that compares equal to k //由于不存在重复的键值,所以返回的元素最多为1个 pair<iterator, iterator> equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } pair<const_iterator, const_iterator> equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } //删除元素 /* by position (1) iterator erase ( const_iterator position ); by key (2) size_type erase ( const key_type& k ); range (3) iterator erase ( const_iterator first, const_iterator last ); */ //擦除指定键值的元素,并返回擦除的个数 //因为键值唯一,则该键值的元素最多为1个 size_type erase(const key_type& __key) {return _M_ht.erase(__key); } //擦除指定位置的元素 void erase(iterator __it) { _M_ht.erase(__it); } //擦除指定范围的元素 void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } //清空hash_map容器 void clear() { _M_ht.clear(); } //调整hash_set容器的容量 void resize(size_type __hint) { _M_ht.resize(__hint); } //Returns the number of buckets in the hash_map container. size_type bucket_count() const { return _M_ht.bucket_count(); } //Returns the maximum number of buckets that the hash_map container can have. size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } //Returns the number of elements in bucket n size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); }//返回指定桶子键值key中list链表的元素个数 }; template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> inline bool operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { return __hm1._M_ht == __hm2._M_ht; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> inline bool operator!=(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { return !(__hm1 == __hm2); } //交换两个hash_map容器的内容 template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> inline void swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { __hm1.swap(__hm2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ ~~~ 参考资料: 《STL源码剖析》侯捷
';

关联容器之hash_multiset

最后更新于:2022-04-01 15:51:11

### 前言      hash_multiset和hash_set的区别就像multiset与set的区别一样,hash_multiset的底层机制是基于hash table,它可以存在重复的键值,所以插入函数使用insert_equal(),hash_multiset和hash_set一样,容器的内容不自动排序。本文源码出自SGI STL的<stl_hash_set.h>文件。 ### hash_multiset源码剖析 ~~~ //以下是hash_multiset的定义 /* hash_multiset是基于底层机制为hash table,hash_multiset的元素不会自动排序,其他功能与multiset类似, hash_multiset与hash_set的区别和multiset与set区别一样, hash_multiset的插入函数是hash table的insert_equal() */ template <class _Value, class _HashFcn __STL_DEPENDENT_DEFAULT_TMPL(hash<_Value>), class _EqualKey __STL_DEPENDENT_DEFAULT_TMPL(equal_to<_Value>), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > class hash_multiset; template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> inline bool operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2); template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> class hash_multiset { // requirements: __STL_CLASS_REQUIRES(_Value, _Assignable); __STL_CLASS_UNARY_FUNCTION_CHECK(_HashFcn, size_t, _Value); __STL_CLASS_BINARY_FUNCTION_CHECK(_EqualKey, bool, _Value, _Value); private: //_Identity获取value值,在hash_set中也是键值,_Identity<>定义在<stl_function.h> /* template <class _Arg, class _Result> struct unary_function { typedef _Arg argument_type; typedef _Result result_type; }; template <class _Tp> struct _Identity : public unary_function<_Tp,_Tp> { const _Tp& operator()(const _Tp& __x) const { return __x; } }; */ typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, _Alloc> _Ht; _Ht _M_ht;//底层机制是hashtable public: typedef typename _Ht::key_type key_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; // 注意: 不能修改hash table内部的元素,reference, pointer, iterator都为const typedef typename _Ht::const_pointer pointer; typedef typename _Ht::const_pointer const_pointer; typedef typename _Ht::const_reference reference; typedef typename _Ht::const_reference const_reference; typedef typename _Ht::const_iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; //返回hash函数 hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } public: //构造函数和hash_set一样,具体可以参照hash_set的讲解 //唯一的区别就是插入函数是insert_equal() hash_multiset() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_multiset(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_multiset(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} #ifdef __STL_MEMBER_TEMPLATES template <class _InputIterator> hash_multiset(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template <class _InputIterator> hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template <class _InputIterator> hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template <class _InputIterator> hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_equal(__f, __l); } #else hash_multiset(const value_type* __f, const value_type* __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multiset(const value_type* __f, const value_type* __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multiset(const value_type* __f, const value_type* __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multiset(const value_type* __f, const value_type* __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_equal(__f, __l); } hash_multiset(const_iterator __f, const_iterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multiset(const_iterator __f, const_iterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multiset(const_iterator __f, const_iterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multiset(const_iterator __f, const_iterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_equal(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ public: //Returns the number of elements in the hash_multiset container size_type size() const { return _M_ht.size(); } //Returns the maximum number of elements that the hash_multiset container can hold. size_type max_size() const { return _M_ht.max_size(); } //Returns a bool value indicating whether the hash_multiset container is empty, //i.e. whether its size is 0. bool empty() const { return _M_ht.empty(); } //交换两个hash_multiset的内容 void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); } #ifdef __STL_MEMBER_TEMPLATES template <class _Val, class _HF, class _EqK, class _Al> friend bool operator== (const hash_multiset<_Val, _HF, _EqK, _Al>&, const hash_multiset<_Val, _HF, _EqK, _Al>&); #else /* __STL_MEMBER_TEMPLATES */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const hash_multiset&,const hash_multiset&); #endif /* __STL_MEMBER_TEMPLATES */ iterator begin() const { return _M_ht.begin(); } iterator end() const { return _M_ht.end(); } public: //插入元素 /* iterator insert ( const value_type& val ); template <class InputIterator> void insert ( InputIterator first, InputIterator last ); */ iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } #ifdef __STL_MEMBER_TEMPLATES template <class _InputIterator> void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } #else void insert(const value_type* __f, const value_type* __l) { _M_ht.insert_equal(__f,__l); } void insert(const_iterator __f, const_iterator __l) { _M_ht.insert_equal(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ iterator insert_noresize(const value_type& __obj) { return _M_ht.insert_equal_noresize(__obj); } //Searches the container for an element with k as key and returns an iterator to it if found, //otherwise it returns an iterator to hash_multiset::end (the element past the end of the container). iterator find(const key_type& __key) const { return _M_ht.find(__key); } //Searches the container for elements with a value of k and returns the number of elements found size_type count(const key_type& __key) const { return _M_ht.count(__key); } //Returns the bounds of a range that includes all the elements in the container that compare equal to k. pair<iterator, iterator> equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } //删除元素 /* by position (1): iterator erase ( const_iterator position ); by key (2): size_type erase ( const key_type& k ); range (3): iterator erase ( const_iterator first, const_iterator last ); */ size_type erase(const key_type& __key) {return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } //清空容器 void clear() { _M_ht.clear(); } public: void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> inline bool operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { return __hs1._M_ht == __hs2._M_ht; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> inline bool operator!=(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { return !(__hs1 == __hs2); } template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> inline void swap(hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { __hs1.swap(__hs2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ ~~~ 参考资料: 《STL源码剖析》侯捷
';

关联容器之hash_set

最后更新于:2022-04-01 15:51:09

### 前言   由于前文介绍的《[散列表](http://blog.csdn.net/chenhanzhun/article/details/39578597)[hashtable](http://blog.csdn.net/chenhanzhun/article/details/39578597)》中,可以知道hash table在查找、删除和插入节点是常数时间,优于RB-Tree红黑树,所以在SGI STL中提供了底层机制基于hash table的hash_set容器,hash_set和set类似,但是不同点是hash_set容器中的元素是没有排序的,因为hash table没有提供排序功能。本文源码出自SGI STL的<stl_hash_set.h>文件。 ### hash_set容器源码剖析 ~~~ #ifndef __SGI_STL_INTERNAL_HASH_SET_H #define __SGI_STL_INTERNAL_HASH_SET_H #include <concept_checks.h> __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif //hash_set的底层是基于hash table的,hash table没有提供排序,所以hash_set容器里面的内容是没排序的 //hash_set和set一样,键值和实值相同,并且键值是唯一的 // Forward declaration of equality operator; needed for friend declaration. //这里提供默认的参数,其中哈希函数在<stl_hash_fun.h>定义 //前面的博文也对哈希函数进行讲解了 //http://blog.csdn.net/chenhanzhun/article/details/39584025 //用户可自行制定 template <class _Value, class _HashFcn __STL_DEPENDENT_DEFAULT_TMPL(hash<_Value>), class _EqualKey __STL_DEPENDENT_DEFAULT_TMPL(equal_to<_Value>), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > class hash_set; template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> inline bool operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2); template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> class hash_set { // requirements: __STL_CLASS_REQUIRES(_Value, _Assignable); __STL_CLASS_UNARY_FUNCTION_CHECK(_HashFcn, size_t, _Value); __STL_CLASS_BINARY_FUNCTION_CHECK(_EqualKey, bool, _Value, _Value); private: //_Identity获取value值,在hash_set中也是键值,_Identity<>定义在<stl_function.h> /* template <class _Arg, class _Result> struct unary_function { typedef _Arg argument_type; typedef _Result result_type; }; template <class _Tp> struct _Identity : public unary_function<_Tp,_Tp> { const _Tp& operator()(const _Tp& __x) const { return __x; } }; */ typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, _Alloc> _Ht; _Ht _M_ht;//hash_set的底层机制是hash table public: //以下的内嵌类型均来时hash table typedef typename _Ht::key_type key_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; // 注意: 不能修改hash table内部的元素,reference, pointer, iterator都为const typedef typename _Ht::const_pointer pointer; typedef typename _Ht::const_pointer const_pointer; typedef typename _Ht::const_reference reference; typedef typename _Ht::const_reference const_reference; typedef typename _Ht::const_iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; //返回hash函数 hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } public: //构造函数 //缺省情况使用大小为100,但是实际分配的空间大小为不小于100的最小素数 //只是空的hash_set,不存储元素节点 hash_set() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} //指定大小n的hash_set表 explicit hash_set(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} //指定大小为n,且指定hash函数的hash_set hash_set(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} //指定大小为n,且指定hash函数和键值比较函数的hash_set hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} #ifdef __STL_MEMBER_TEMPLATES //以下hash_set的插入操作使用hash table的insert_unique插入 //不允许有相同的键值插入 //用某个范围的元素初始化hash_set对象 //相当于把某个范围[f,l)插入到空的hash_set template <class _InputIterator> hash_set(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); }//调用hash table的插入函数 template <class _InputIterator> hash_set(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template <class _InputIterator> hash_set(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template <class _InputIterator> hash_set(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_unique(__f, __l); } #else hash_set(const value_type* __f, const value_type* __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_set(const value_type* __f, const value_type* __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_set(const value_type* __f, const value_type* __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_set(const value_type* __f, const value_type* __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_unique(__f, __l); } hash_set(const_iterator __f, const_iterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_set(const_iterator __f, const_iterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_set(const_iterator __f, const_iterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_set(const_iterator __f, const_iterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_unique(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ public: //以下的函数操作只是调用hash table的成员函数 size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); } #ifdef __STL_MEMBER_TEMPLATES template <class _Val, class _HF, class _EqK, class _Al> friend bool operator== (const hash_set<_Val, _HF, _EqK, _Al>&, const hash_set<_Val, _HF, _EqK, _Al>&); #else /* __STL_MEMBER_TEMPLATES */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const hash_set&, const hash_set&); #endif /* __STL_MEMBER_TEMPLATES */ iterator begin() const { return _M_ht.begin(); } iterator end() const { return _M_ht.end(); } public: /* 插入元素 (1) pair<iterator,bool> insert ( const value_type& val ); (2) template <class InputIterator> void insert ( InputIterator first, InputIterator last ); */ //不允许有重复的键值 //返回pair第二个参数second若为true则插入成功 pair<iterator, bool> insert(const value_type& __obj) { //调用hash table的insert_unique()函数 pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj); return pair<iterator,bool>(__p.first, __p.second); } #ifdef __STL_MEMBER_TEMPLATES template <class _InputIterator> void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f,__l); } #else void insert(const value_type* __f, const value_type* __l) { _M_ht.insert_unique(__f,__l); } void insert(const_iterator __f, const_iterator __l) {_M_ht.insert_unique(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ pair<iterator, bool> insert_noresize(const value_type& __obj) { pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique_noresize(__obj); return pair<iterator, bool>(__p.first, __p.second); } //查找键值对应的元素,并且返回该元素的节点位置 iterator find(const key_type& __key) const { return _M_ht.find(__key); } //返回键值为key的节点元素个数 size_type count(const key_type& __key) const { return _M_ht.count(__key); } //Returns the bounds of a range that includes all the elements that compare equal to k. //In hash_set containers, where keys are unique, the range will include one element at most. pair<iterator, iterator> equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } //擦除指定键值的元素,并返回擦除的个数 //因为键值唯一,则该键值的元素最多为1个 size_type erase(const key_type& __key) {return _M_ht.erase(__key); } //擦除指定位置的元素 void erase(iterator __it) { _M_ht.erase(__it); } //擦除指定范围的元素 void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } //清除hash_set容器 void clear() { _M_ht.clear(); } public: //调整hash_set容器的容量 void resize(size_type __hint) { _M_ht.resize(__hint); } //Returns the number of buckets in the hash_set container. size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } //Returns the number of elements in bucket n size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); }//返回指定桶子键值key中list链表的元素个数 }; template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> inline bool operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) { return __hs1._M_ht == __hs2._M_ht; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> inline bool operator!=(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) { return !(__hs1 == __hs2); } //交换两个hash_set容器的内容 template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> inline void swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { __hs1.swap(__hs2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ ~~~ 参考资料: 《STL源码剖析》侯捷
';

stl_hash_fun.h学习

最后更新于:2022-04-01 15:51:07

### 前言   在SGI STL中hash表的实现是采用拉链法,其中用到了哈希函数,哈希函数的作用是把元素键值映射到对应的桶子里面,一般哈希值是键值对桶子数取余。在SGI STL提供的哈希函数是有限的,只支持特定的元素类型,若用户需要使用其他类型的哈希函数,则必须自行定义。定义的时候注意一下几点: 1. 使用struct,然后重载operator(). 1. 返回是size_t 1. 参数是你要hash的key的类型。 1. 函数是const类型的。   例如定义string类型的哈希函数: ~~~ struct str_hash{ size_t operator()(const string& str) const { unsigned long __h = 0; for (size_t i = 0 ; i < str.size() ; i ++) __h = 5*__h + str[i]; return size_t(__h); } }; ~~~ ### hash函数源码剖析 ~~~ #ifndef __SGI_STL_HASH_FUN_H #define __SGI_STL_HASH_FUN_H #include <stddef.h> __STL_BEGIN_NAMESPACE //hash function 是计算元素位置的函数 //这些函数可以对hashtable进行取模运算 //这是hashtable所提供的散列函数是取模运算决定的 /* SGI hashtable以下有限的定义类型: struct hash<char*> struct hash<const char*> struct hash<char> struct hash<unsigned char> struct hash<signed char> struct hash<short> struct hash<unsigned short> struct hash<int> struct hash<unsigned int> struct hash<long> struct hash<unsigned long> 不在这里定义的类型,不能使用,若用户想要使用,则必须自己定义。例如:string,double,float */ /*定义自己的哈希函数时要注意以下几点: [1]使用struct,然后重载operator(). [2]返回是size_t [3]参数是你要hash的key的类型。 [4]函数是const类型的。 */ template <class _Key> struct hash { }; //对const char* 提供字符串转换函数 inline size_t __stl_hash_string(const char* __s) { unsigned long __h = 0; for ( ; *__s; ++__s) __h = 5*__h + *__s; return size_t(__h); } __STL_TEMPLATE_NULL struct hash<char*> { size_t operator()(const char* __s) const { return __stl_hash_string(__s); } }; __STL_TEMPLATE_NULL struct hash<const char*> { size_t operator()(const char* __s) const { return __stl_hash_string(__s); } }; //下面的hash函数都是直接返回原值 //对于char,unsigned char,signed char,int,unsigned int, //short, unsigned short, long,unsigned long都只是返回数值本身 __STL_TEMPLATE_NULL struct hash<char> { size_t operator()(char __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<unsigned char> { size_t operator()(unsigned char __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<signed char> { size_t operator()(unsigned char __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<short> { size_t operator()(short __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<unsigned short> { size_t operator()(unsigned short __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<int> { size_t operator()(int __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<unsigned int> { size_t operator()(unsigned int __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<long> { size_t operator()(long __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<unsigned long> { size_t operator()(unsigned long __x) const { return __x; } }; __STL_END_NAMESPACE #endif /* __SGI_STL_HASH_FUN_H */ // Local Variables: // mode:C++ // End: ~~~
';

散列表hashtable

最后更新于:2022-04-01 15:51:04

### 前言   前面介绍的关联容器set、multiset、map和multimap的底层机制都是基于RB-Tree红黑树,虽然能够实现在插入、删除和搜素操作能够达到对数平均时间,可是要求输入数据有足够的随机性。本文介绍的hash table不需要要求输入数据具有随机性,在插入、删除和搜素操作都能达到常数平均时间。本文介绍的hash table是来自SGI STL中的<stl_hashtable.h>文件,在这里为了避免冲突(即不同元素映射到相同的键值位置),采用了拉链法来解决冲突问题。SGI中实现hash table的方式,在每个表格元素中维护一个链表, 然后在链表上执行元素的插入、搜寻、删除等操作,该表格中的每个元素被称为桶(bucket)。有关hash table的介绍可往前面博文《[散列表](http://blog.csdn.net/chenhanzhun/article/details/38091431)》查看。 ### hashtable散列表源码剖析 ~~~ #ifndef __SGI_STL_INTERNAL_HASHTABLE_H #define __SGI_STL_INTERNAL_HASHTABLE_H // Hashtable class, used to implement the hashed associative containers // hash_set, hash_map, hash_multiset, and hash_multimap. //SGI STL的hashtable的实现方法是拉链法. //拉链法可以避免hashtable的冲突问题,即不同数据映射到同一的hash值 //有关hashtable的介绍见前文: //http://blog.csdn.net/chenhanzhun/article/details/38091431 #include <stl_algobase.h> #include <stl_alloc.h> #include <stl_construct.h> #include <stl_tempbuf.h> #include <stl_algo.h> #include <stl_uninitialized.h> #include <stl_function.h> #include <stl_vector.h> #include <stl_hash_fun.h> __STL_BEGIN_NAMESPACE //hashtable中链表的节点结构 //类似于单链表的节点结构 template <class _Val> struct _Hashtable_node { _Hashtable_node* _M_next;//指向下一节点 _Val _M_val;//节点元素值 }; //这里使用前置声明, 避免在后面交叉引用会导致编译错误 template <class _Val, class _Key, class _HashFcn, class _ExtractKey, class _EqualKey, class _Alloc = alloc> class hashtable; template <class _Val, class _Key, class _HashFcn, class _ExtractKey, class _EqualKey, class _Alloc> struct _Hashtable_iterator; template <class _Val, class _Key, class _HashFcn, class _ExtractKey, class _EqualKey, class _Alloc> struct _Hashtable_const_iterator; //hashtable迭代器定义 //注意:hash table迭代器没有提供后退操作operator-- //也没用提供逆向迭代器reverse iterator template <class _Val, class _Key, class _HashFcn, class _ExtractKey, class _EqualKey, class _Alloc> struct _Hashtable_iterator { //内嵌类型别名 typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> _Hashtable; typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> iterator; typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> const_iterator; typedef _Hashtable_node<_Val> _Node; typedef forward_iterator_tag iterator_category;//采用正向迭代器 typedef _Val value_type; typedef ptrdiff_t difference_type; typedef size_t size_type; typedef _Val& reference; typedef _Val* pointer; _Node* _M_cur;//当前迭代器所指位置 _Hashtable* _M_ht;//hashtable中的位置,控制访问桶子连续性 _Hashtable_iterator(_Node* __n, _Hashtable* __tab) : _M_cur(__n), _M_ht(__tab) {} _Hashtable_iterator() {} //返回当前节点元素值的引用 reference operator*() const { return _M_cur->_M_val; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ //操作符重载定义在后面定义 iterator& operator++(); iterator operator++(int); //比较两个迭代器是否指向同一个节点 bool operator==(const iterator& __it) const { return _M_cur == __it._M_cur; } bool operator!=(const iterator& __it) const { return _M_cur != __it._M_cur; } }; //下面是const iterator的定义,基本和上面相同 template <class _Val, class _Key, class _HashFcn, class _ExtractKey, class _EqualKey, class _Alloc> struct _Hashtable_const_iterator { typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> _Hashtable; typedef _Hashtable_iterator<_Val,_Key,_HashFcn, _ExtractKey,_EqualKey,_Alloc> iterator; typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> const_iterator; typedef _Hashtable_node<_Val> _Node; typedef forward_iterator_tag iterator_category; typedef _Val value_type; typedef ptrdiff_t difference_type; typedef size_t size_type; typedef const _Val& reference; typedef const _Val* pointer; const _Node* _M_cur; const _Hashtable* _M_ht; _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) : _M_cur(__n), _M_ht(__tab) {} _Hashtable_const_iterator() {} _Hashtable_const_iterator(const iterator& __it) : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {} reference operator*() const { return _M_cur->_M_val; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ const_iterator& operator++(); const_iterator operator++(int); bool operator==(const const_iterator& __it) const { return _M_cur == __it._M_cur; } bool operator!=(const const_iterator& __it) const { return _M_cur != __it._M_cur; } }; // Note: assumes long is at least 32 bits. // 注意:假设long至少为32-bits, 可以根据自己需要修改 //定义28个素数用作hashtable的大小 enum { __stl_num_primes = 28 }; static const unsigned long __stl_prime_list[__stl_num_primes] = { 53ul, 97ul, 193ul, 389ul, 769ul, 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, 1610612741ul, 3221225473ul, 4294967291ul }; //返回大于n的最小素数 inline unsigned long __stl_next_prime(unsigned long __n) { const unsigned long* __first = __stl_prime_list; const unsigned long* __last = __stl_prime_list + (int)__stl_num_primes; const unsigned long* pos = lower_bound(__first, __last, __n); /* 上面的lower_bound调用的是STL中的算法lower_bound(); 该算法的功能: Returns an iterator pointing to the first element in the range [first,last) which does not compare less than val. The elements in the range shall already be sorted according to this same criterion (operator< or comp) 即返回在[first,last)范围内第一个不小于val的位置 注意:调用该算法之前,[first,last)范围里面的元素必须已排序 该算法的原型如下: 第一个版本:采用默认比较准则operator< template <class ForwardIterator, class T> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val); 第二版本:采用用户指定的比较函数comp template <class ForwardIterator, class T, class Compare> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); 其实该算法的实现机制使用二分查找法进行查找元素val: template <class ForwardIterator, class T> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val) { ForwardIterator it; iterator_traits<ForwardIterator>::difference_type count, step; count = distance(first,last); while (count>0) { it = first; step=count/2; advance (it,step); if (*it<val) { // or: if (comp(*it,val)), for version (2) first=++it; count-=step+1; } else count=step; } return first; } 下面给出例子:lower_bound/upper_bound example #include <iostream> // std::cout #include <algorithm> // std::lower_bound, std::upper_bound, std::sort #include <vector> // std::vector int main () { int myints[] = {10,20,30,30,20,10,10,20}; std::vector<int> v(myints,myints+8); // 10 20 30 30 20 10 10 20 std::sort (v.begin(), v.end()); // 10 10 10 20 20 20 30 30 std::vector<int>::iterator low,up; low=std::lower_bound (v.begin(), v.end(), 20); // ^ up= std::upper_bound (v.begin(), v.end(), 20); // ^ std::cout << "lower_bound at position " << (low- v.begin()) << '\n'; std::cout << "upper_bound at position " << (up - v.begin()) << '\n'; return 0; } Output: lower_bound at position 3 upper_bound at position 6 */ return pos == __last ? *(__last - 1) : *pos; } // Forward declaration of operator==. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> class hashtable; template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2); // Hashtables handle allocators a bit differently than other containers // do. If we're using standard-conforming allocators, then a hashtable // unconditionally has a member variable to hold its allocator, even if // it so happens that all instances of the allocator type are identical. // This is because, for hashtables, this extra storage is negligible. // Additionally, a base class wouldn't serve any other purposes; it // wouldn't, for example, simplify the exception-handling code. //hash table的定义 //模板参数定义 /* Value: 节点的实值类型 Key: 节点的键值类型 HashFcn: hash function的类型 ExtractKey:从节点中取出键值的方法(函数或仿函数) EqualKey:判断键值是否相同的方法(函数或仿函数) Alloc:空间配置器 */ //hash table的线性表是用vector容器维护 template <class _Val, class _Key, class _HashFcn, class _ExtractKey, class _EqualKey, class _Alloc> class hashtable { public: typedef _Key key_type; typedef _Val value_type; typedef _HashFcn hasher; typedef _EqualKey key_equal; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; hasher hash_funct() const { return _M_hash; } key_equal key_eq() const { return _M_equals; } private: typedef _Hashtable_node<_Val> _Node; #ifdef __STL_USE_STD_ALLOCATORS public: typedef typename _Alloc_traits<_Val,_Alloc>::allocator_type allocator_type; allocator_type get_allocator() const { return _M_node_allocator; } private: typename _Alloc_traits<_Node, _Alloc>::allocator_type _M_node_allocator; _Node* _M_get_node() { return _M_node_allocator.allocate(1); } void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } # define __HASH_ALLOC_INIT(__a) _M_node_allocator(__a), #else /* __STL_USE_STD_ALLOCATORS */ public: typedef _Alloc allocator_type; allocator_type get_allocator() const { return allocator_type(); } private: typedef simple_alloc<_Node, _Alloc> _M_node_allocator_type; _Node* _M_get_node() { return _M_node_allocator_type::allocate(1); } void _M_put_node(_Node* __p) { _M_node_allocator_type::deallocate(__p, 1); } # define __HASH_ALLOC_INIT(__a) #endif /* __STL_USE_STD_ALLOCATORS */ //以下是hash table的成员变量 private: hasher _M_hash; key_equal _M_equals; _ExtractKey _M_get_key; vector<_Node*,_Alloc> _M_buckets;//用vector维护buckets size_type _M_num_elements;//hashtable中list节点个数 public: typedef _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> iterator; typedef _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey, _Alloc> const_iterator; friend struct _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; friend struct _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; public: //构造函数 hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql, const _ExtractKey& __ext, const allocator_type& __a = allocator_type()) : __HASH_ALLOC_INIT(__a) _M_hash(__hf), _M_equals(__eql), _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0) { _M_initialize_buckets(__n);//预留空间,并将其初始化为空0 //预留空间大小为大于n的最小素数 } hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql, const allocator_type& __a = allocator_type()) : __HASH_ALLOC_INIT(__a) _M_hash(__hf), _M_equals(__eql), _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0) { _M_initialize_buckets(__n); } //拷贝构造函数 hashtable(const hashtable& __ht) : __HASH_ALLOC_INIT(__ht.get_allocator()) _M_hash(__ht._M_hash), _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key), _M_buckets(__ht.get_allocator()), _M_num_elements(0) { _M_copy_from(__ht);//复制hashtable内容 } #undef __HASH_ALLOC_INIT //可以通过operator=初始化hashtable对象 hashtable& operator= (const hashtable& __ht) { if (&__ht != this) { clear(); _M_hash = __ht._M_hash; _M_equals = __ht._M_equals; _M_get_key = __ht._M_get_key; _M_copy_from(__ht); } return *this; } ~hashtable() { clear(); } //返回hashtable元素的个数 size_type size() const { return _M_num_elements; } size_type max_size() const { return size_type(-1); } bool empty() const { return size() == 0; } //交换两个hashtable的内容 void swap(hashtable& __ht) { __STD::swap(_M_hash, __ht._M_hash); __STD::swap(_M_equals, __ht._M_equals); __STD::swap(_M_get_key, __ht._M_get_key); _M_buckets.swap(__ht._M_buckets); __STD::swap(_M_num_elements, __ht._M_num_elements); } iterator begin() { for (size_type __n = 0; __n < _M_buckets.size(); ++__n) if (_M_buckets[__n])//若hashtable中的桶子_M_buckets有链表list return iterator(_M_buckets[__n], this);//返回链表的第一个节点位置 return end();//若list链表为空,则返回尾端end(),其实这里尾端和起始端一样 } iterator end() { return iterator(0, this); }//返回桶子list链表的null指针,即尾端 const_iterator begin() const { for (size_type __n = 0; __n < _M_buckets.size(); ++__n) if (_M_buckets[__n]) return const_iterator(_M_buckets[__n], this); return end(); } const_iterator end() const { return const_iterator(0, this); } #ifdef __STL_MEMBER_TEMPLATES template <class _Vl, class _Ky, class _HF, class _Ex, class _Eq, class _Al> friend bool operator== (const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); #else /* __STL_MEMBER_TEMPLATES */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const hashtable&, const hashtable&); #endif /* __STL_MEMBER_TEMPLATES */ public: //返回桶子个数,即线性表中节点数 size_type bucket_count() const { return _M_buckets.size(); } //线性表最多分配节点数 size_type max_bucket_count() const { return __stl_prime_list[(int)__stl_num_primes - 1]; } //指定桶子键值key中list链表的元素个数 size_type elems_in_bucket(size_type __bucket) const { size_type __result = 0; for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next) __result += 1; return __result; } //插入元素节点,不允许存在重复元素 pair<iterator, bool> insert_unique(const value_type& __obj) { //判断容量是否够用, 否则就重新配置 resize(_M_num_elements + 1); //插入元素,不允许存在重复元素 return insert_unique_noresize(__obj); } //插入元素节点,允许存在重复元素 iterator insert_equal(const value_type& __obj) {//判断容量是否够用, 否则就重新配置 resize(_M_num_elements + 1); //插入元素,允许存在重复元素 return insert_equal_noresize(__obj); } //具体定义见hashtable类外后面的剖析 pair<iterator, bool> insert_unique_noresize(const value_type& __obj); iterator insert_equal_noresize(const value_type& __obj); #ifdef __STL_MEMBER_TEMPLATES template <class _InputIterator> void insert_unique(_InputIterator __f, _InputIterator __l) { insert_unique(__f, __l, __ITERATOR_CATEGORY(__f)); } template <class _InputIterator> void insert_equal(_InputIterator __f, _InputIterator __l) { insert_equal(__f, __l, __ITERATOR_CATEGORY(__f)); } template <class _InputIterator> void insert_unique(_InputIterator __f, _InputIterator __l, input_iterator_tag) { for ( ; __f != __l; ++__f) insert_unique(*__f); } template <class _InputIterator> void insert_equal(_InputIterator __f, _InputIterator __l, input_iterator_tag) { for ( ; __f != __l; ++__f) insert_equal(*__f); } template <class _ForwardIterator> void insert_unique(_ForwardIterator __f, _ForwardIterator __l, forward_iterator_tag) { size_type __n = 0; distance(__f, __l, __n); resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_unique_noresize(*__f); } template <class _ForwardIterator> void insert_equal(_ForwardIterator __f, _ForwardIterator __l, forward_iterator_tag) { size_type __n = 0; distance(__f, __l, __n); resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_equal_noresize(*__f); } #else /* __STL_MEMBER_TEMPLATES */ void insert_unique(const value_type* __f, const value_type* __l) { size_type __n = __l - __f; resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_unique_noresize(*__f); } void insert_equal(const value_type* __f, const value_type* __l) { size_type __n = __l - __f; resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_equal_noresize(*__f); } void insert_unique(const_iterator __f, const_iterator __l) { size_type __n = 0; distance(__f, __l, __n); resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_unique_noresize(*__f); } void insert_equal(const_iterator __f, const_iterator __l) { size_type __n = 0; distance(__f, __l, __n); resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_equal_noresize(*__f); } #endif /*__STL_MEMBER_TEMPLATES */ reference find_or_insert(const value_type& __obj); //查找指定键值的元素 iterator find(const key_type& __key) { size_type __n = _M_bkt_num_key(__key);//获取键值 _Node* __first; for ( __first = _M_buckets[__n]; __first && !_M_equals(_M_get_key(__first->_M_val), __key); __first = __first->_M_next) {} return iterator(__first, this); } const_iterator find(const key_type& __key) const { size_type __n = _M_bkt_num_key(__key); const _Node* __first; for ( __first = _M_buckets[__n]; __first && !_M_equals(_M_get_key(__first->_M_val), __key); __first = __first->_M_next) {} return const_iterator(__first, this); } //返回键值为key的元素的个数 size_type count(const key_type& __key) const { const size_type __n = _M_bkt_num_key(__key); size_type __result = 0; for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), __key)) ++__result; return __result; } pair<iterator, iterator> equal_range(const key_type& __key); pair<const_iterator, const_iterator> equal_range(const key_type& __key) const; //擦除元素 size_type erase(const key_type& __key); void erase(const iterator& __it); void erase(iterator __first, iterator __last); void erase(const const_iterator& __it); void erase(const_iterator __first, const_iterator __last); void resize(size_type __num_elements_hint); void clear(); private: //返回大于n的最小素数 //实际上调用__stl_next_prime(__n); size_type _M_next_size(size_type __n) const { return __stl_next_prime(__n); } //预留空间,并将其初始化为0 void _M_initialize_buckets(size_type __n) { //返回大于n的最小素数__n_buckets const size_type __n_buckets = _M_next_size(__n); //这里调用vector的成员函数reserve //reserve该函数功能是改变可用空间的大小 //Requests that the vector capacity be at least enough to contain __n_buckets elements. _M_buckets.reserve(__n_buckets); //调用vector的插入函数insert //在原始end后面连续插入__n_buckets个0 _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); _M_num_elements = 0; } //获取键值key在桶子的位置 size_type _M_bkt_num_key(const key_type& __key) const { return _M_bkt_num_key(__key, _M_buckets.size()); } //获取在桶子的序号,也就是键值 //输入参数是实值value size_type _M_bkt_num(const value_type& __obj) const { return _M_bkt_num_key(_M_get_key(__obj)); } size_type _M_bkt_num_key(const key_type& __key, size_t __n) const { return _M_hash(__key) % __n;//采用除法取余hash函数 } size_type _M_bkt_num(const value_type& __obj, size_t __n) const { return _M_bkt_num_key(_M_get_key(__obj), __n); } //分配节点空间,并构造对象 _Node* _M_new_node(const value_type& __obj) { _Node* __n = _M_get_node(); __n->_M_next = 0; __STL_TRY { construct(&__n->_M_val, __obj); return __n; } __STL_UNWIND(_M_put_node(__n)); } //析构对象,并释放空间 void _M_delete_node(_Node* __n) { destroy(&__n->_M_val); _M_put_node(__n); } void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); void _M_erase_bucket(const size_type __n, _Node* __last); void _M_copy_from(const hashtable& __ht); }; //前缀operator++重载,前进一个list节点 template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() { const _Node* __old = _M_cur; _M_cur = _M_cur->_M_next;//若存在,则返回 //若当前节点为空,则需前进到下一个桶子的节点 if (!_M_cur) { //根据元素值,定位出下一个bucket的位置,其起始位置就是我们的目的地 size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) _M_cur = _M_ht->_M_buckets[__bucket]; } return *this; } //后缀operator++重载 template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) { iterator __tmp = *this; ++*this;//调用operator++ return __tmp; } template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() { const _Node* __old = _M_cur; _M_cur = _M_cur->_M_next; if (!_M_cur) { size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) _M_cur = _M_ht->_M_buckets[__bucket]; } return *this; } template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) { const_iterator __tmp = *this; ++*this; return __tmp; } #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> inline forward_iterator_tag iterator_category(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { return forward_iterator_tag(); } template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> inline _Val* value_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { return (_Val*) 0; } template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type* distance_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0; } template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> inline forward_iterator_tag iterator_category(const _Hashtable_const_iterator<_Val,_Key,_HF, _ExK,_EqK,_All>&) { return forward_iterator_tag(); } template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> inline _Val* value_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { return (_Val*) 0; } template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type* distance_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) { typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node; if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) return false; for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) { _Node* __cur1 = __ht1._M_buckets[__n]; _Node* __cur2 = __ht2._M_buckets[__n]; for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val; __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) {} if (__cur1 || __cur2) return false; } return true; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) { return !(__ht1 == __ht2); } template <class _Val, class _Key, class _HF, class _Extract, class _EqKey, class _All> inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { __ht1.swap(__ht2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ //插入元素,不需要重新调整内存空间,不允许存在重复元素 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool> hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::insert_unique_noresize(const value_type& __obj) { //获取待插入元素在hashtable中的桶子位置 const size_type __n = _M_bkt_num(__obj); _Node* __first = _M_buckets[__n]; //判断hashtable中是否存在与之相等的键值元素 //若存在则不插入 //否则插入该元素 for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) return pair<iterator, bool>(iterator(__cur, this), false); //把元素插入到第一个节点位置 _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements; return pair<iterator, bool>(iterator(__tmp, this), true); } //插入元素,允许重复,不需要分配新的空间 //也就是说有足够的空间 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::insert_equal_noresize(const value_type& __obj) { //获取待插入元素在hashtable中的桶子位置 const size_type __n = _M_bkt_num(__obj); _Node* __first = _M_buckets[__n]; for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) //若存在键值相同的元素,则插在相同元素下一个位置 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) { _Node* __tmp = _M_new_node(__obj);//创建新节点 __tmp->_M_next = __cur->_M_next;//将新节点插在当前节点之后 __cur->_M_next = __tmp; ++_M_num_elements;//节点数加1 return iterator(__tmp, this);//返回指向新增节点迭代器 } //若不存在相同键值的元素,则插在第一个位置 _Node* __tmp = _M_new_node(__obj);//创建新节点 __tmp->_M_next = __first;//插入在链表表头 _M_buckets[__n] = __tmp; ++_M_num_elements;//节点数加1 return iterator(__tmp, this);//返回指向新增节点的迭代器 } template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj) { resize(_M_num_elements + 1); size_type __n = _M_bkt_num(__obj); _Node* __first = _M_buckets[__n]; for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) return __cur->_M_val; _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements; return __tmp->_M_val; } template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator> hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key) { typedef pair<iterator, iterator> _Pii; const size_type __n = _M_bkt_num_key(__key); for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next) if (_M_equals(_M_get_key(__first->_M_val), __key)) { for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) if (!_M_equals(_M_get_key(__cur->_M_val), __key)) return _Pii(iterator(__first, this), iterator(__cur, this)); for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) if (_M_buckets[__m]) return _Pii(iterator(__first, this), iterator(_M_buckets[__m], this)); return _Pii(iterator(__first, this), end()); } return _Pii(end(), end()); } template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator, typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator> hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::equal_range(const key_type& __key) const { typedef pair<const_iterator, const_iterator> _Pii; const size_type __n = _M_bkt_num_key(__key); for (const _Node* __first = _M_buckets[__n] ; __first; __first = __first->_M_next) { if (_M_equals(_M_get_key(__first->_M_val), __key)) { for (const _Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) if (!_M_equals(_M_get_key(__cur->_M_val), __key)) return _Pii(const_iterator(__first, this), const_iterator(__cur, this)); for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) if (_M_buckets[__m]) return _Pii(const_iterator(__first, this), const_iterator(_M_buckets[__m], this)); return _Pii(const_iterator(__first, this), end()); } } return _Pii(end(), end()); } template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key) { const size_type __n = _M_bkt_num_key(__key); _Node* __first = _M_buckets[__n]; size_type __erased = 0; if (__first) { _Node* __cur = __first; _Node* __next = __cur->_M_next; while (__next) { if (_M_equals(_M_get_key(__next->_M_val), __key)) { __cur->_M_next = __next->_M_next; _M_delete_node(__next); __next = __cur->_M_next; ++__erased; --_M_num_elements; } else { __cur = __next; __next = __cur->_M_next; } } if (_M_equals(_M_get_key(__first->_M_val), __key)) { _M_buckets[__n] = __first->_M_next; _M_delete_node(__first); ++__erased; --_M_num_elements; } } return __erased; } template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it) { _Node* __p = __it._M_cur; if (__p) { const size_type __n = _M_bkt_num(__p->_M_val); _Node* __cur = _M_buckets[__n]; if (__cur == __p) { _M_buckets[__n] = __cur->_M_next; _M_delete_node(__cur); --_M_num_elements; } else { _Node* __next = __cur->_M_next; while (__next) { if (__next == __p) { __cur->_M_next = __next->_M_next; _M_delete_node(__next); --_M_num_elements; break; } else { __cur = __next; __next = __cur->_M_next; } } } } } template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::erase(iterator __first, iterator __last) { size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); if (__first._M_cur == __last._M_cur) return; else if (__f_bucket == __l_bucket) _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); else { _M_erase_bucket(__f_bucket, __first._M_cur, 0); for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) _M_erase_bucket(__n, 0); if (__l_bucket != _M_buckets.size()) _M_erase_bucket(__l_bucket, __last._M_cur); } } template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> inline void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first, const_iterator __last) { erase(iterator(const_cast<_Node*>(__first._M_cur), const_cast<hashtable*>(__first._M_ht)), iterator(const_cast<_Node*>(__last._M_cur), const_cast<hashtable*>(__last._M_ht))); } template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> inline void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it) { erase(iterator(const_cast<_Node*>(__it._M_cur), const_cast<hashtable*>(__it._M_ht))); } //调整hashtable的容量 //新的容量大小为__num_elements_hint template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::resize(size_type __num_elements_hint) { //hashtable原始大小 const size_type __old_n = _M_buckets.size(); if (__num_elements_hint > __old_n) {//若新的容量大小比原始的大 //查找不低于__num_elements_hint的最小素数 const size_type __n = _M_next_size(__num_elements_hint); if (__n > __old_n) { //创建新的线性表,容量为__n,只是起到中介作用 vector<_Node*, _All> __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); __STL_TRY {//以下是复制数据 for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { _Node* __first = _M_buckets[__bucket]; while (__first) { //获取实值在新桶子的键值位置 size_type __new_bucket = _M_bkt_num(__first->_M_val, __n); //这个只是为了方便while循环里面__first的迭代 _M_buckets[__bucket] = __first->_M_next; //将当前节点插入到新的桶子__new_bucket里面,成为list的第一个节点 __first->_M_next = __tmp[__new_bucket];//__first->_M_next指向null指针,因为新桶子是空的 __tmp[__new_bucket] = __first;//新桶子对应键值指向第一个节点 __first = _M_buckets[__bucket];//更新当前指针 } } _M_buckets.swap(__tmp);//交换内容 } # ifdef __STL_USE_EXCEPTIONS catch(...) {//释放临时hashtable的线性表tmp for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) { while (__tmp[__bucket]) { _Node* __next = __tmp[__bucket]->_M_next; _M_delete_node(__tmp[__bucket]); __tmp[__bucket] = __next; } } throw; } # endif /* __STL_USE_EXCEPTIONS */ } } } template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) { _Node* __cur = _M_buckets[__n]; if (__cur == __first) _M_erase_bucket(__n, __last); else { _Node* __next; for (__next = __cur->_M_next; __next != __first; __cur = __next, __next = __cur->_M_next) ; while (__next != __last) { __cur->_M_next = __next->_M_next; _M_delete_node(__next); __next = __cur->_M_next; --_M_num_elements; } } } template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::_M_erase_bucket(const size_type __n, _Node* __last) { _Node* __cur = _M_buckets[__n]; while (__cur != __last) { _Node* __next = __cur->_M_next; _M_delete_node(__cur); __cur = __next; _M_buckets[__n] = __cur; --_M_num_elements; } } //清空hashtable,但是没有释放bucket vector空间 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear() { for (size_type __i = 0; __i < _M_buckets.size(); ++__i) {//遍历每个桶子 _Node* __cur = _M_buckets[__i];//当前节点为桶子的第一个节点 while (__cur != 0) {//遍历桶子维护的链表,并释放每个链表节点 _Node* __next = __cur->_M_next; _M_delete_node(__cur); __cur = __next; } _M_buckets[__i] = 0;//桶子链表为空 } _M_num_elements = 0;//链表节点数为0 } //拷贝hashtable对象 //实现机制:首先把原始对象清空,再把空间变成被复制对象__ht一样的大小 //最后把__ht的内容复制到目标对象 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::_M_copy_from(const hashtable& __ht) {//_M_buckets是vector维护的,可以调用vector的成员函数 _M_buckets.clear();//清空线性表调用vector::clear() _M_buckets.reserve(__ht._M_buckets.size());//把线性表内存空间变成与__ht一样大 //在_M_buckets vector尾端插入size个元素,初始值为空指针 //注意:此时_M_buckets vector为空,即尾端也是起始端 _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); __STL_TRY {//开始复制操作 for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { //复制vector的每一个元素(是指向hashtable节点指针) const _Node* __cur = __ht._M_buckets[__i]; if (__cur) { _Node* __copy = _M_new_node(__cur->_M_val); _M_buckets[__i] = __copy; //针对每一个hashtable节点对应的list,复制list的每一个节点 for (_Node* __next = __cur->_M_next; __next; __cur = __next, __next = __cur->_M_next) { __copy->_M_next = _M_new_node(__next->_M_val); __copy = __copy->_M_next; } } } _M_num_elements = __ht._M_num_elements;//更新节点个数 } __STL_UNWIND(clear()); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_HASHTABLE_H */ // Local Variables: // mode:C++ // End: ~~~ 参考资料: 《STL源码剖析》侯捷
';

关联容器之multimap

最后更新于:2022-04-01 15:51:02

### 前言       multimap的特性及其用法和map完全相同,唯一的区别就是multimap允许键值key重复,因此multimap的插入操作采用的是底层RB-Tree的insert_equal()而非insert_unique(),有关map容器的介绍前往博文《[关联容器之map](http://blog.csdn.net/chenhanzhun/article/details/39529425)》。本文的源码出自SGI STL中的<stl_multimap.h>文件。 ### multimap容器源码剖析 ~~~ #ifndef __SGI_STL_INTERNAL_MULTIMAP_H #define __SGI_STL_INTERNAL_MULTIMAP_H #include <concept_checks.h> __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif // Forward declaration of operators < and ==, needed for friend declaration. //multimap的特性及其用法和map完全相同,唯一的区别就是multimap允许键值key重复 //因此multimap的插入操作采用的是底层RB-Tree的insert_equal()而非insert_unique() //有关map容器的剖析见前面博文 //map内部元素根据键值key默认使用递增排序less //用户可自行制定比较类型 //内部维护的数据结构是红黑树, 具有非常优秀的最坏情况的时间复杂度 //注意:multimap允许元素重复,即键值和实值都可以重复,这点与map不同 template <class _Key, class _Tp, class _Compare __STL_DEPENDENT_DEFAULT_TMPL(less<_Key>), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > class multimap; template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y); template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y); template <class _Key, class _Tp, class _Compare, class _Alloc> class multimap { // requirements: __STL_CLASS_REQUIRES(_Tp, _Assignable); __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key); public: // typedefs: //下面的定义与map相同 typedef _Key key_type; typedef _Tp data_type; typedef _Tp mapped_type; typedef pair<const _Key, _Tp> value_type; typedef _Compare key_compare; //嵌套类,提供键值key比较函数接口 //继承自<stl_function.h>中的binary_function /* template <class _Arg1, class _Arg2, class _Result> struct binary_function { typedef _Arg1 first_argument_type; typedef _Arg2 second_argument_type; typedef _Result result_type; }; */ class value_compare : public binary_function<value_type, value_type, bool> { friend class multimap<_Key,_Tp,_Compare,_Alloc>; protected: _Compare comp; value_compare(_Compare __c) : comp(__c) {} public: bool operator()(const value_type& __x, const value_type& __y) const { return comp(__x.first, __y.first); } }; private: //底层机制是RB-Tree typedef _Rb_tree<key_type, value_type, _Select1st<value_type>, key_compare, _Alloc> _Rep_type; _Rep_type _M_t; // red-black tree representing multimap public: typedef typename _Rep_type::pointer pointer; typedef typename _Rep_type::const_pointer const_pointer; typedef typename _Rep_type::reference reference; typedef typename _Rep_type::const_reference const_reference; //map的迭代器不直接定义为const_iterator,而是分别定义iterator,const_iterator //是因为map的键值key不能被修改,因为必须遵守比较函数的排序规则,所以必须定义为const_iterator //而map的实值value可以被修改,则定义为iterator typedef typename _Rep_type::iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; typedef typename _Rep_type::reverse_iterator reverse_iterator; typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; typedef typename _Rep_type::size_type size_type; typedef typename _Rep_type::difference_type difference_type; typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation // 注意:multimap只能使用RB-tree的insert-equal(),不能使用insert-unique() /* 构造函数 multimap(); explicit multimap (const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()); template <class InputIterator> multimap (InputIterator first, InputIterator last, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()); multimap (const multimap& x); */ multimap() : _M_t(_Compare(), allocator_type()) { } explicit multimap(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { } #ifdef __STL_MEMBER_TEMPLATES template <class _InputIterator> multimap(_InputIterator __first, _InputIterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } template <class _InputIterator> multimap(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } #else multimap(const value_type* __first, const value_type* __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } multimap(const value_type* __first, const value_type* __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } multimap(const_iterator __first, const_iterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } multimap(const_iterator __first, const_iterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ //拷贝构造函数 multimap(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) { } //这里提供了operator=,即可以通过=初始化对象 multimap<_Key,_Tp,_Compare,_Alloc>& operator=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t = __x._M_t; return *this; } // accessors: //返回键值的比较函数,这里是调用RB-Tree的key_comp() key_compare key_comp() const { return _M_t.key_comp(); } //返回实值的比较函数 //这里调用的是map嵌套类中定义的比较函数 /* class value_compare : public binary_function<value_type, value_type, bool> { friend class map<_Key,_Tp,_Compare,_Alloc>; protected : _Compare comp; value_compare(_Compare __c) : comp(__c) {} public: bool operator()(const value_type& __x, const value_type& __y) const { return comp(__x.first, __y.first);//以键值调用比较函数 } */ //实际上最终还是调用键值key的比较函数,即他们是调用同一个比较函数 value_compare value_comp() const { return value_compare(_M_t.key_comp()); } allocator_type get_allocator() const { return _M_t.get_allocator(); } iterator begin() { return _M_t.begin(); } const_iterator begin() const { return _M_t.begin(); } iterator end() { return _M_t.end(); } const_iterator end() const { return _M_t.end(); } reverse_iterator rbegin() { return _M_t.rbegin(); } const_reverse_iterator rbegin() const { return _M_t.rbegin(); } reverse_iterator rend() { return _M_t.rend(); } const_reverse_iterator rend() const { return _M_t.rend(); } //判断容器multimap是否为空 bool empty() const { return _M_t.empty(); } //返回容器multimap的大小 size_type size() const { return _M_t.size(); } size_type max_size() const { return _M_t.max_size(); } //交换multimap对象的内容 void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase /* multimap只能使用RB-tree的insert-equal() 插入元素 iterator insert (const value_type& val); iterator insert (iterator position, const value_type& val); template <class InputIterator> void insert (InputIterator first, InputIterator last); */ //插入元素节点,调用RB-Tree的insert-equal(); //插入元素的键值key允许重复 iterator insert(const value_type& __x) { return _M_t.insert_equal(__x); } //在指定位置插入元素 iterator insert(iterator __position, const value_type& __x) { return _M_t.insert_equal(__position, __x); } #ifdef __STL_MEMBER_TEMPLATES //插入[first,last)元素 template <class _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { _M_t.insert_equal(__first, __last); } #else void insert(const value_type* __first, const value_type* __last) { _M_t.insert_equal(__first, __last); } void insert(const_iterator __first, const_iterator __last) { _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ /* 擦除元素 void erase (iterator position); size_type erase (const key_type& k); void erase (iterator first, iterator last); */ //在指定位置擦除元素 void erase(iterator __position) { _M_t.erase(__position); } //擦除指定键值的节点 size_type erase(const key_type& __x) { return _M_t.erase(__x); } //擦除指定区间的节点 void erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); } //清空容器 void clear() { _M_t.clear(); } // multimap operations: //查找指定键值的节点 iterator find(const key_type& __x) { return _M_t.find(__x); } const_iterator find(const key_type& __x) const { return _M_t.find(__x); } //计算指定键值元素的个数 size_type count(const key_type& __x) const { return _M_t.count(__x); } //Returns an iterator pointing to the first element in the container //whose key is not considered to go before k (i.e., either it is equivalent or goes after). //this->first is greater than or equivalent to __x. iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); } const_iterator lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } //Returns an iterator pointing to the first element that is greater than key. iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); } const_iterator upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); } //Returns the bounds of a range that includes all the elements in the container //which have a key equivalent to k //Because the elements in a map container have unique keys, //the range returned will contain a single element at most. pair<iterator,iterator> equal_range(const key_type& __x) { return _M_t.equal_range(__x); } pair<const_iterator,const_iterator> equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } //以下是操作符重载 #ifdef __STL_TEMPLATE_FRIENDS template <class _K1, class _T1, class _C1, class _A1> friend bool operator== (const multimap<_K1, _T1, _C1, _A1>&, const multimap<_K1, _T1, _C1, _A1>&); template <class _K1, class _T1, class _C1, class _A1> friend bool operator< (const multimap<_K1, _T1, _C1, _A1>&, const multimap<_K1, _T1, _C1, _A1>&); #else /* __STL_TEMPLATE_FRIENDS */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const multimap&, const multimap&); friend bool __STD_QUALIFIER operator< __STL_NULL_TMPL_ARGS (const multimap&, const multimap&); #endif /* __STL_TEMPLATE_FRIENDS */ }; template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return __x._M_t == __y._M_t; } template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__x == __y); } template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return __y < __x; } template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__y < __x); } template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__x < __y); } template <class _Key, class _Tp, class _Compare, class _Alloc> inline void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x, multimap<_Key,_Tp,_Compare,_Alloc>& __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_MULTIMAP_H */ // Local Variables: // mode:C++ // End: ~~~ 参考资料: 《STL源码剖析》侯捷
';

关联容器之multiset

最后更新于:2022-04-01 15:51:00

### 前言      multiset的特性及其用法和set完全相同,唯一的区别就是multiset允许键值key重复,因此multiset的插入操作采用的是底层RB-Tree的insert_equal()而非insert_unique(),有关set容器的介绍前往博文《[STL源码剖析——关联容器之set](http://blog.csdn.net/chenhanzhun/article/details/39525489)》。本文的源码出自SGI STL中的<stl_multiset.h>文件。 ### multiset容器源码剖析 ~~~ #ifndef __SGI_STL_INTERNAL_MULTISET_H #define __SGI_STL_INTERNAL_MULTISET_H #include <concept_checks.h> __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif //multiset的特性及其用法和set完全相同,唯一的区别就是multiset允许键值key重复 //因此multiset的插入操作采用的是底层RB-Tree的insert_equal()而非insert_unique() //有关set容器的剖析见前面博文 // Forward declaration of operators < and ==, needed for friend declaration. //multiset内部元素默认使用递增排序less //用户可自行制定比较类型 //内部维护的数据结构是红黑树, 具有非常优秀的最坏情况的时间复杂度 template <class _Key, class _Compare __STL_DEPENDENT_DEFAULT_TMPL(less<_Key>), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > class multiset; template <class _Key, class _Compare, class _Alloc> inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y); template <class _Key, class _Compare, class _Alloc> inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y); template <class _Key, class _Compare, class _Alloc> class multiset { // requirements: __STL_CLASS_REQUIRES(_Key, _Assignable); __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key); public: // typedefs: //以下的定义与set相同 typedef _Key key_type; typedef _Key value_type; typedef _Compare key_compare; typedef _Compare value_compare; private: //底层机制是采用RB-Tree typedef _Rb_tree<key_type, value_type, _Identity<value_type>, key_compare, _Alloc> _Rep_type; _Rep_type _M_t; // red-black tree representing multiset public: typedef typename _Rep_type::const_pointer pointer; typedef typename _Rep_type::const_pointer const_pointer; typedef typename _Rep_type::const_reference reference; typedef typename _Rep_type::const_reference const_reference; typedef typename _Rep_type::const_iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; typedef typename _Rep_type::const_reverse_iterator reverse_iterator; typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; typedef typename _Rep_type::size_type size_type; typedef typename _Rep_type::difference_type difference_type; typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation /* 构造函数 multiset(); explicit multiset (const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()); template <class InputIterator> multiset (InputIterator first, InputIterator last, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()); multiset (const multiset& x); */ multiset() : _M_t(_Compare(), allocator_type()) {} explicit multiset(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) {} #ifdef __STL_MEMBER_TEMPLATES //multiset的插入操作采用的是底层RB-Tree的insert_equal()而非insert_unique() template <class _InputIterator> multiset(_InputIterator __first, _InputIterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } template <class _InputIterator> multiset(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } #else multiset(const value_type* __first, const value_type* __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } multiset(const value_type* __first, const value_type* __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } multiset(const_iterator __first, const_iterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } multiset(const_iterator __first, const_iterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ multiset(const multiset<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} multiset<_Key,_Compare,_Alloc>& operator=(const multiset<_Key,_Compare,_Alloc>& __x) { _M_t = __x._M_t;//调用了底层红黑树的operator=操作函数 return *this; } //以下所有的multiset操作行为,RB-tree都已提供,所以multiset只要调用即可 // accessors: //返回用于key比较的函数,调用RB-Tree的key_comp() key_compare key_comp() const { return _M_t.key_comp(); } //由于multiset的性质, value和key使用同一个比较函数 value_compare value_comp() const { return _M_t.key_comp(); } allocator_type get_allocator() const { return _M_t.get_allocator(); } iterator begin() const { return _M_t.begin(); } iterator end() const { return _M_t.end(); } reverse_iterator rbegin() const { return _M_t.rbegin(); } reverse_iterator rend() const { return _M_t.rend(); } bool empty() const { return _M_t.empty(); } size_type size() const { return _M_t.size(); } size_type max_size() const { return _M_t.max_size(); } //这里调用的swap()函数是专属于RB-Tree的swap(),并不是STL的swap()算法 void swap(multiset<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase /* 插入节点 iterator insert (const value_type& val); iterator insert (iterator position, const value_type& val); template <class InputIterator> void insert (InputIterator first, InputIterator last); */ //插入数据节点 iterator insert(const value_type& __x) { return _M_t.insert_equal(__x); } //在指定位置插入节点 iterator insert(iterator __position, const value_type& __x) { typedef typename _Rep_type::iterator _Rep_iterator; return _M_t.insert_equal((_Rep_iterator&)__position, __x); } #ifdef __STL_MEMBER_TEMPLATES template <class _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { _M_t.insert_equal(__first, __last); } #else void insert(const value_type* __first, const value_type* __last) { _M_t.insert_equal(__first, __last); } void insert(const_iterator __first, const_iterator __last) { _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ //擦除指定位置的元素 void erase(iterator __position) { typedef typename _Rep_type::iterator _Rep_iterator; _M_t.erase((_Rep_iterator&)__position); } //擦除元素值为x的节点 size_type erase(const key_type& __x) { return _M_t.erase(__x); } //擦除指定区间的节点 void erase(iterator __first, iterator __last) { typedef typename _Rep_type::iterator _Rep_iterator; _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); } //清除multiset void clear() { _M_t.clear(); } // multiset operations: //查找元素值为x的节点 iterator find(const key_type& __x) const { return _M_t.find(__x); } //返回指定元素的个数 size_type count(const key_type& __x) const { return _M_t.count(__x); } //Returns an iterator pointing to the first element in the container //whose key is not considered to go before k (i.e., either it is equivalent or goes after). iterator lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } //Returns an iterator pointing to the first element that is greater than key. iterator upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); } //Returns the bounds of a range that includes all the elements in the container //which have a key equivalent to k //Because the elements in a map container have unique keys, //the range returned will contain a single element at most. pair<iterator,iterator> equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } //以下是操作符的重载 #ifdef __STL_TEMPLATE_FRIENDS template <class _K1, class _C1, class _A1> friend bool operator== (const multiset<_K1,_C1,_A1>&, const multiset<_K1,_C1,_A1>&); template <class _K1, class _C1, class _A1> friend bool operator< (const multiset<_K1,_C1,_A1>&, const multiset<_K1,_C1,_A1>&); #else /* __STL_TEMPLATE_FRIENDS */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const multiset&, const multiset&); friend bool __STD_QUALIFIER operator< __STL_NULL_TMPL_ARGS (const multiset&, const multiset&); #endif /* __STL_TEMPLATE_FRIENDS */ }; template <class _Key, class _Compare, class _Alloc> inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return __x._M_t == __y._M_t; } template <class _Key, class _Compare, class _Alloc> inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template <class _Key, class _Compare, class _Alloc> inline bool operator!=(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return !(__x == __y); } template <class _Key, class _Compare, class _Alloc> inline bool operator>(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return __y < __x; } template <class _Key, class _Compare, class _Alloc> inline bool operator<=(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return !(__y < __x); } template <class _Key, class _Compare, class _Alloc> inline bool operator>=(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return !(__x < __y); } template <class _Key, class _Compare, class _Alloc> inline void swap(multiset<_Key,_Compare,_Alloc>& __x, multiset<_Key,_Compare,_Alloc>& __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_MULTISET_H */ // Local Variables: // mode:C++ // End: ~~~ 参考资料: 《STL源码剖析》侯捷
';

关联容器之map

最后更新于:2022-04-01 15:50:57

### 前言   在SGI STL中的容器map,底层实现机制是RB-Tree,是因为map的操作RB-Tree都能实现,有关RB-Tree的剖析请看《[STL源码剖析——RB-Tree](http://blog.csdn.net/chenhanzhun/article/details/39523519)[(红黑树)](http://blog.csdn.net/chenhanzhun/article/details/39523519)》。在map容器键值key和实值value是不相同的,键值key和实值value的比较函数也是不同的。在容器里面的元素是根据元素的键值自动排序的,不能修改map容器的键值,但是可以修改容器的实值。map的所有节点元素都是pair,pair有两个成员变量first,second;第一个first是键值key,第二个second是实值value;有关pair的介绍见前文《[stl_pair.h学习](http://blog.csdn.net/chenhanzhun/article/details/39526719)》剖析。本文的源码出自SGI STL中的<stl_map.h>文件。 ### map容器源码剖析   在源码剖析的时候,会针对一些函数给出例子,例子包含在剖析文件里面。 ~~~ #ifndef __SGI_STL_INTERNAL_MAP_H #define __SGI_STL_INTERNAL_MAP_H #include <concept_checks.h> __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif /* map的所有节点元素都是pair,pair有两个成员变量first,second 第一个first是键值key,第二个second是实值value 有关pair的定义见前文<stl_pair.h>剖析 */ //map内部元素根据键值key默认使用递增排序less //用户可自行制定比较类型 //内部维护的数据结构是红黑树, 具有非常优秀的最坏情况的时间复杂度 //注意:map键值和实值是分开的,map的键值key是唯一的,实值value可以重复 //不能通过迭代器修改map的键值key,其迭代器类型是定义为RB-Tree的const_iterator //但是可以通过迭代器修改map的实值value // Forward declarations of operators == and <, needed for friend declarations. template <class _Key, class _Tp, class _Compare __STL_DEPENDENT_DEFAULT_TMPL(less<_Key>), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > class map; template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y); template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y); //map定义 template <class _Key, class _Tp, class _Compare, class _Alloc> class map { public: // requirements: __STL_CLASS_REQUIRES(_Tp, _Assignable); __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key); // typedefs: typedef _Key key_type;//键值key类型 typedef _Tp data_type;//数据(实值)value类型 typedef _Tp mapped_type; typedef pair<const _Key, _Tp> value_type;//元素型别,包含(键值/实值),const保证键值key不被修改 typedef _Compare key_compare;//键值key比较函数 //嵌套类,提供键值key比较函数接口 //继承自<stl_function.h>中的binary_function /* template <class _Arg1, class _Arg2, class _Result> struct binary_function { typedef _Arg1 first_argument_type; typedef _Arg2 second_argument_type; typedef _Result result_type; }; */ class value_compare : public binary_function<value_type, value_type, bool> { friend class map<_Key,_Tp,_Compare,_Alloc>; protected : _Compare comp; value_compare(_Compare __c) : comp(__c) {} public: bool operator()(const value_type& __x, const value_type& __y) const { return comp(__x.first, __y.first);//以键值调用比较函数 } }; private: //底层机制是RB-Tree //以map类型(一个pair)的第一个类型作为TB-tree的键值类型. //所以在RB-tree中,键值key不能修改 typedef _Rb_tree<key_type, value_type, _Select1st<value_type>, key_compare, _Alloc> _Rep_type; _Rep_type _M_t; // red-black tree representing map public: typedef typename _Rep_type::pointer pointer; typedef typename _Rep_type::const_pointer const_pointer; typedef typename _Rep_type::reference reference; typedef typename _Rep_type::const_reference const_reference; //map的迭代器不直接定义为const_iterator,而是分别定义iterator,const_iterator //是因为map的键值key不能被修改,所以必须定义为const_iterator //而map的实值value可以被修改,则定义为iterator typedef typename _Rep_type::iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; typedef typename _Rep_type::reverse_iterator reverse_iterator; typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; typedef typename _Rep_type::size_type size_type; typedef typename _Rep_type::difference_type difference_type; typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation // map只能使用RB-tree的insert-unique(),不能使用insert-equal() //因为必须保证键值唯一 /* 构造函数 map(); explicit map (const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()); template <class InputIterator> map (InputIterator first, InputIterator last, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()); map (const map& x); */ /* example: #include <iostream> #include <map> bool fncomp (char lhs, char rhs) {return lhs<rhs;} struct classcomp { bool operator() (const char& lhs, const char& rhs) const {return lhs<rhs;} }; int main () { std::map<char,int> first; first['a']=10; first['b']=30; first['c']=50; first['d']=70; std::map<char,int> second (first.begin(),first.end()); std::map<char,int> third (second); std::map<char,int,classcomp> fourth; // class as Compare bool(*fn_pt)(char,char) = fncomp; std::map<char,int,bool(*)(char,char)> fifth (fn_pt); // function pointer as Compare return 0; } */ map() : _M_t(_Compare(), allocator_type()) {} explicit map(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) {} #ifdef __STL_MEMBER_TEMPLATES template <class _InputIterator> map(_InputIterator __first, _InputIterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_unique(__first, __last); } template <class _InputIterator> map(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } #else map(const value_type* __first, const value_type* __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_unique(__first, __last); } map(const value_type* __first, const value_type* __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } map(const_iterator __first, const_iterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_unique(__first, __last); } map(const_iterator __first, const_iterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ //拷贝构造函数 map(const map<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} //这里提供了operator=,即可以通过=初始化对象 map<_Key,_Tp,_Compare,_Alloc>& operator=(const map<_Key, _Tp, _Compare, _Alloc>& __x) { _M_t = __x._M_t; return *this; } // accessors: //以下调用RB-Tree的操作 //返回键值的比较函数,这里是调用RB-Tree的key_comp() key_compare key_comp() const { return _M_t.key_comp(); } //返回实值的比较函数 //这里调用的是map嵌套类中定义的比较函数 /* class value_compare : public binary_function<value_type, value_type, bool> { friend class map<_Key,_Tp,_Compare,_Alloc>; protected : _Compare comp; value_compare(_Compare __c) : comp(__c) {} public: bool operator()(const value_type& __x, const value_type& __y) const { return comp(__x.first, __y.first);//以键值调用比较函数 } */ //实际上最终还是调用键值key的比较函数,即他们是调用同一个比较函数 value_compare value_comp() const { return value_compare(_M_t.key_comp()); } //获得分配器的类型 allocator_type get_allocator() const { return _M_t.get_allocator(); } iterator begin() { return _M_t.begin(); } const_iterator begin() const { return _M_t.begin(); } iterator end() { return _M_t.end(); } const_iterator end() const { return _M_t.end(); } reverse_iterator rbegin() { return _M_t.rbegin(); } const_reverse_iterator rbegin() const { return _M_t.rbegin(); } reverse_iterator rend() { return _M_t.rend(); } const_reverse_iterator rend() const { return _M_t.rend(); } bool empty() const { return _M_t.empty(); } size_type size() const { return _M_t.size(); } size_type max_size() const { return _M_t.max_size(); } //重载operator[],返回是实值value(即pair.second)的引用 //注意:若你原先没有定义map对象,即你访问的键值key不存在,则会自动新建一个map对象 //键值key为你访问的键值key,实值value为空,看下面的例子就明白了 _Tp& operator[](const key_type& __k) { iterator __i = lower_bound(__k); // __i->first is greater than or equivalent to __k. if (__i == end() || key_comp()(__k, (*__i).first)) __i = insert(__i, value_type(__k, _Tp())); return (*__i).second; //其实简单的方式是直接返回 //return (*((insert(value_type(k, T()))).first)).second; } /* example: #include <iostream> #include <map> #include <string> int main () { std::map<char,std::string> mymap; mymap['a']="an element"; mymap['b']="another element"; mymap['c']=mymap['b']; std::cout << "mymap['a'] is " << mymap['a'] << '\n'; std::cout << "mymap['b'] is " << mymap['b'] << '\n'; std::cout << "mymap['c'] is " << mymap['c'] << '\n'; std::cout << "mymap['d'] is " << mymap['d'] << '\n'; std::cout << "mymap now contains " << mymap.size() << " elements.\n"; return 0; } Ouput: mymap['a'] is an element mymap['b'] is another element mymap['c'] is another element mymap['d'] is mymap now contains 4 elements. */ //交换map对象的内容 void swap(map<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase /* 插入元素 single element (1): pair<iterator,bool> insert (const value_type& val); with hint (2): iterator insert (iterator position, const value_type& val); range (3): template <class InputIterator> void insert (InputIterator first, InputIterator last); */ //插入元素节点,调用RB-Tree的insert_unique(__x); //不能插入相同键值的元素 pair<iterator,bool> insert(const value_type& __x) { return _M_t.insert_unique(__x); } //在指定位置插入元素,但是会先遍历该集合,判断是否存在相同元素 //若不存在才在指定位置插入该元素 iterator insert(iterator position, const value_type& __x) { return _M_t.insert_unique(position, __x); } #ifdef __STL_MEMBER_TEMPLATES template <class _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { _M_t.insert_unique(__first, __last); } #else void insert(const value_type* __first, const value_type* __last) { _M_t.insert_unique(__first, __last); } void insert(const_iterator __first, const_iterator __last) { _M_t.insert_unique(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ /* 擦除元素 void erase (iterator position); size_type erase (const key_type& k); void erase (iterator first, iterator last); */ //在指定位置擦除元素 void erase(iterator __position) { _M_t.erase(__position); } //擦除指定键值的节点 size_type erase(const key_type& __x) { return _M_t.erase(__x); } //擦除指定区间的节点 void erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); } //清空map void clear() { _M_t.clear(); } // map operations: //查找指定键值的节点 iterator find(const key_type& __x) { return _M_t.find(__x); } const_iterator find(const key_type& __x) const { return _M_t.find(__x); } //计算指定键值元素的个数 size_type count(const key_type& __x) const { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } /* Example: #include <iostream> #include <map> int main () { std::map<char,int> mymap; std::map<char,int>::iterator itlow,itup; mymap['a']=20; mymap['b']=40; mymap['c']=60; mymap['d']=80; mymap['e']=100; itlow=mymap.lower_bound ('b'); // itlow points to b itup=mymap.upper_bound ('d'); // itup points to e (not d!) mymap.erase(itlow,itup); // erases [itlow,itup) // print content: for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it) std::cout << it->first << " => " << it->second << '\n'; return 0; } Output: a => 20 e => 100 */ //Returns an iterator pointing to the first element in the container //whose key is not considered to go before k (i.e., either it is equivalent or goes after). //this->first is greater than or equivalent to __x. iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); } const_iterator lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } //Returns an iterator pointing to the first element that is greater than key. iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); } const_iterator upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); } //Returns the bounds of a range that includes all the elements in the container //which have a key equivalent to k //Because the elements in a map container have unique keys, //the range returned will contain a single element at most. pair<iterator,iterator> equal_range(const key_type& __x) { return _M_t.equal_range(__x); } pair<const_iterator,const_iterator> equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } /* Example: #include <iostream> #include <map> int main () { std::map<char,int> mymap; mymap['a']=10; mymap['b']=20; mymap['c']=30; std::pair<std::map<char,int>::iterator,std::map<char,int>::iterator> ret; ret = mymap.equal_range('b'); std::cout << "lower bound points to: "; std::cout << ret.first->first << " => " << ret.first->second << '\n'; std::cout << "upper bound points to: "; std::cout << ret.second->first << " => " << ret.second->second << '\n'; return 0; } Output: lower bound points to: 'b' => 20 upper bound points to: 'c' => 30 */ //以下是操作符重载 #ifdef __STL_TEMPLATE_FRIENDS template <class _K1, class _T1, class _C1, class _A1> friend bool operator== (const map<_K1, _T1, _C1, _A1>&, const map<_K1, _T1, _C1, _A1>&); template <class _K1, class _T1, class _C1, class _A1> friend bool operator< (const map<_K1, _T1, _C1, _A1>&, const map<_K1, _T1, _C1, _A1>&); #else /* __STL_TEMPLATE_FRIENDS */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const map&, const map&); friend bool __STD_QUALIFIER operator< __STL_NULL_TMPL_ARGS (const map&, const map&); #endif /* __STL_TEMPLATE_FRIENDS */ }; //比较两个map的内容 template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return __x._M_t == __y._M_t; } template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__x == __y); } template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return __y < __x; } template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__y < __x); } template <class _Key, class _Tp, class _Compare, class _Alloc> inline bool operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__x < __y); } template <class _Key, class _Tp, class _Compare, class _Alloc> inline void swap(map<_Key,_Tp,_Compare,_Alloc>& __x, map<_Key,_Tp,_Compare,_Alloc>& __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_MAP_H */ // Local Variables: // mode:C++ // End: ~~~ 参考资料: 《STL源码剖析》侯捷 《[STL源码剖析-- stl_map.h](http://blog.csdn.net/mdl13412/article/details/6655581)》
';