STL算法_基本算法篇

来源:互联网 发布:软件高级工程师待遇 编辑:程序博客网 时间:2024/06/05 18:37

STL算法_基本算法

1)equal算法:用来比较两个序列在[first,last)区间内是否相等。如果第二个序列的元素多于第一个序列元素,则多出的元素不予考虑。

// equal算法用来判断两个序列在[frist,last)区间内是否相等。当第二个序列的元素较多时,多出来的元素不予考虑。// 版本1template <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;                       // 至此,全部相等,返回true}// 版本2template <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;  return true;}

2)fill算法:将[first,last)内的所有元素改填新值。

// fill算法用来将[first,last)内的所有元素改填新值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;                    // 设定新值}// 版本2// 特例化,针对单字节类型使用memset函数实现inline void fill(unsigned char* __first, unsigned char* __last,                 const unsigned char& __c) {  unsigned char __tmp = __c;  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);}

3)fill_n算法:将[first,last)内的前n个元素改填新值,返回的迭代器指向被填入的最后一个元素的下一个位置。

// fill_n算法用来将[first,last)内的前n个元素改填新值,返回的迭代器指向被填入的最后一个元素的下一位置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)    // 经过n个元素    *__first = __value;                 // 设定新值  return __first;}// 版本2#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDERtemplate <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;}

4)iter_swap算法:将两个ForwardIterator所指对象对调。它是迭代器value type派上用场的一个好例子。该函数必须知道迭代器的value type,才能够据此声明一个对象,用来暂时存放迭代器所指对象。

// iter_swap算法:将两个ForwardIterator所指对象对调。它是迭代器value type派上用场的一个好例子。// 该函数必须知道迭代器的value type,才能够据此声明一个对象,用来暂时存放迭代器所指对象。template <class _ForwardIter1, class _ForwardIter2, class _Tp>inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) {  _Tp __tmp = *__a;     // 执行交换过程  *__a = *__b;  *__b = __tmp;}// iter_swap算法用来将两个ForwardIterator所指对象对调。它是迭代器值value type派上用场的一个好例子。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);  __iter_swap(__a, __b, __VALUE_TYPE(__a));}

5)lexicographical_compare算法:以“字典排列方式”对两个序列[first1,last1)和[firs2,last2)进行比较。比较操作针对两序列中的对应位置上的元素进行,并持续直到1)某一组对应元素彼此不相等;2)同时到达last1和last2(当两序列的大小相同);3)到达last1或last2(当两序列的大小不同)。

这两个函数在对应位置上发现第一组不相等的元素时,有以下几种可能:1)如果第一序列的元素较小,返回true,否则返回false;2)如果到达last1而尚未到达last2,返回true;3)如果达到last2而尚未到达last1,返回false;4)如果同时到达last1和last2(即所有元素都匹配)返回false。

// lexicographical_compare算法用来以“字典排列方式”对两个序列[first1,last1)和[firs2,last2)进行比较。// 版本1template <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;    if (*__first2 < *__first1)   // 第二序列元素值小于第一序列的相应元素值      return false;  // 如果不符合以上两条件,表示两值相等,那就进行下一组相应元素值的比对  }  // 进行到这里,如果第一序列到达尾端而第二序列尚有余额,那么第一序列小于第二序列  return __first1 == __last1 && __first2 != __last2;}// 版本2template <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;    if (__comp(*__first2, *__first1))      return false;  }  return __first1 == __last1 && __first2 != __last2;}// lexicograhical_compare算法用来以“字典排列方式”对两个序列[first1,last1)和[firs2,last2)进行比较。// 下面利用原生指针const unsigned char *实现// 版本3inline 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;      // 第二序列长度  const int __result = memcmp(__first1, __first2, min(__len1, __len2));   // 先比较相同长度的一段。memcmp()速度极快  return __result != 0 ? __result < 0 : __len1 < __len2;                  // 如果不相上下,则长度较长者被视为比较大}// 版本4inline 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 */}

6)max算法:取两个对象中的较大值。

// max算法用来取两个对象中的较大值// 版本1template <class _Tp>inline const _Tp& max(const _Tp& __a, const _Tp& __b) {  __STL_REQUIRES(_Tp, _LessThanComparable);  return  __a < __b ? __b : __a;}// 版本2template <class _Tp, class _Compare>inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) {  return __comp(__a, __b) ? __b : __a;     // 有comp决定“大小比较”标准}

7)min算法:取两个对象中的较小值。

// min算法用来取两个对象中的较小值// 版本1template <class _Tp>inline const _Tp& min(const _Tp& __a, const _Tp& __b) {  __STL_REQUIRES(_Tp, _LessThanComparable);  return __b < __a ? __b : __a;}// 版本2template <class _Tp, class _Compare>inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) {  return __comp(__b, __a) ? __b : __a;}

8)mismatch算法:用来平行比较两个序列,指出两者之间的第一个不匹配点。返回一对迭代器,分别指向两序列中的不匹配点。如果两序列的所有对应元素都匹配,返回的便是两序列各自的last迭代器。如果第二序列的元素个数比第一序列多,多出来的元素忽略不计。如果第二序列的元素个数比第一序列少,会发生未可预测的行为。

// mismath算法用来平行比较两个序列,指出两者之间的第一个不匹配点。返回一对迭代器,分别指向两序列中的不匹配点。// 版本1template <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);}// 版本2template <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);}

9)swap算法:用来交换(对调)两个对象的内容。

// swap算法用来交换(对调)两个对象的内容template <class _Tp>inline void swap(_Tp& __a, _Tp& __b) {  __STL_REQUIRES(_Tp, _Assignable);  _Tp __tmp = __a;    // 执行交换过程  __a = __b;  __b = __tmp;}

10)copy算法:将输入区间[first,last)内的元素赋值到输出区间[result,result+(last-first))内。它返回一个迭代器:result+(last-first)。copy对其template参数所要求的条件非常宽松。其输入区间只需有Input构成,输出区间只需由OutputIterator构成即可。copy算法,将任何容器的任何一段区间的内容,复制到任何容器的任何一段区间上。copy算法为了提高效率,使用了各种方法,包括:函数重载、型别特性、偏特化等编程技巧。

// copy算法用来将[first,last)内的元素复制到输出区间[result,result+(last-first))内// InputIterator版本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;  return __result;}// RandomAccessIterator版本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) {   // 以n决定循环的次数。速度快    *__result = *__first;    ++__first;    ++__result;  }  return __result;}// 以下版本适用于“指针所指对象具备trival assignment operator”template <class _Tp>inline _Tp*__copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) {  memmove(__result, __first, sizeof(_Tp) * (__last - __first));  return __result + (__last - __first);}#if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER)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));}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__template <class _Tp>inline _Tp* __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result,                        __true_type) {  return __copy_trivial(__first, __last, __result);}#endif /* __USLC__ */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;  return __copy_aux2(__first, __last, __result, _Trivial());}template <class _InputIter, class _OutputIter>inline _OutputIter copy(_InputIter __first, _InputIter __last,                        _OutputIter __result) {  __STL_REQUIRES(_InputIter, _InputIterator);  __STL_REQUIRES(_OutputIter, _OutputIterator);  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);  }};// copy函数的泛化版本中调用一个__copy_dispatch()函数,此函数有一个完全泛化版本和两个偏特化版本// 偏特化版本(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

11)copy_backward算法:将[first,last)区间内的每一个元素,以逆性的方向复制到以result-1为起点,方向亦为逆行的区间上。返回一个迭代器:result-(last-first)。copy_backward所接受的迭代器必须是BidirectionalIterators,才能够“倒行逆施”。使用copy_backward算法,可将任何容器的任何一段区间的内容,复制到任何容器的任何一段区间上。如果输入区间和输出区间完全没有重叠,则毫无问题,否则需特别注意。

// copy_backward算法用来将[first,last)区间内的每一个元素,以逆行的方向复制到以result-1为起点,方向亦为逆行的区间上。// BidirectionalIter版本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;  return __result;}// RandomAccessIter班本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;  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);  }};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;  }};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 */// copy_backward算法:将[first,last)区间内的每一个元素,以逆性的方向复制到以result-1为起点,方向亦为逆行的区间上。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源码剖析——侯捷

    STL源码

0 0