欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

STL算法_基本算法篇

程序员文章站 2022-03-24 22:14:59
1)equal算法:用来比较两个序列在[first,last)区间内是否相等。如果第二个序列的元素多于第一个序列元素,则多出的元素不予考虑。 // equal算法用来判断两个序列在[frist,...

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

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

inline void fill(char* __first, char* __last, const char& __c) {
  char __tmp = __c;
  memset(__first, static_cast(__tmp), __last - __first);
}

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

// fill_n算法用来将[first,last)内的前n个元素改填新值,返回的迭代器指向被填入的最后一个元素的下一位置
template 
_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_order
template 
inline unsigned char* fill_n(unsigned char* __first, _size __n,
                             const unsigned char& __c) {
  fill(__first, __first + __n, __c);
  return __first + __n;
}

template 
inline signed char* fill_n(char* __first, _size __n,
                           const signed char& __c) {
  fill(__first, __first + __n, __c);
  return __first + __n;
}

template 
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 
inline void __iter_swap(_forwarditer1 __a, _forwarditer2 __b, _tp*) {
  _tp __tmp = *__a;     // 执行交换过程
  *__a = *__b;
  *__b = __tmp;
}
// iter_swap算法用来将两个forwarditerator所指对象对调。它是迭代器值value type派上用场的一个好例子。
template 
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)进行比较。
// 版本1
template 
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;
}
// 版本2
template 
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 *实现
// 版本3
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;      // 第二序列长度
  const int __result = memcmp(__first1, __first2, min(__len1, __len2));   // 先比较相同长度的一段。memcmp()速度极快
  return __result != 0 ? __result < 0 : __len1 < __len2;                  // 如果不相上下,则长度较长者被视为比较大
}
// 版本4
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 */
}

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

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

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

// min算法用来取两个对象中的较小值
// 版本1
template 
inline const _tp& min(const _tp& __a, const _tp& __b) {
  __stl_requires(_tp, _lessthancomparable);
  return __b < __a ? __b : __a;
}
// 版本2
template 
inline const _tp& min(const _tp& __a, const _tp& __b, _compare __comp) {
  return __comp(__b, __a) ? __b : __a;
}

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

// mismath算法用来平行比较两个序列,指出两者之间的第一个不匹配点。返回一对迭代器,分别指向两序列中的不匹配点。
// 版本1
template 
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);
}
// 版本2
template 
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 
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 
inline _outputiter __copy(_inputiter __first, _inputiter __last,
                          _outputiter __result,
                          input_iterator_tag, _distance*)
{
  for ( ; __first != __last; ++__result, ++__first)   // 以迭代器等同与否,决定循环是否继续。速度慢
    *__result = *__first;
  return __result;
}
// randomaccessiterator版本
template 
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 
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 
inline _outputiter __copy_aux2(_inputiter __first, _inputiter __last,
                               _outputiter __result, __false_type) {
  return __copy(__first, __last, __result,
                __iterator_category(__first),
                __distance_type(__first));
}
template 
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 
inline _tp* __copy_aux2(_tp* __first, _tp* __last, _tp* __result,
                        __true_type) {
  return __copy_trivial(__first, __last, __result);
}
#endif /* __uslc__ */
template 
inline _tp* __copy_aux2(const _tp* __first, const _tp* __last, _tp* __result,
                        __true_type) {
  return __copy_trivial(__first, __last, __result);
}
template 
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 
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 
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 
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 
struct __copy_dispatch
{
  static _tp* copy(const _tp* __first, const _tp* __last, _tp* __result) {
    return __copy_trivial(__first, __last, __result);
  }
};
// 完全泛化版本
template 
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 
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 
inline _bidirectionaliter2 __copy_backward(_bidirectionaliter1 __first, 
                                           _bidirectionaliter1 __last, 
                                           _bidirectionaliter2 __result,
                                           bidirectional_iterator_tag,
                                           _distance*)
{
  while (__first != __last)
    *--__result = *--__last;
  return __result;
}
// randomaccessiter班本
template 
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 
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 
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 
struct __copy_backward_dispatch
{
  static _tp* copy(const _tp* __first, const _tp* __last, _tp* __result) {
    return  __copy_backward_dispatch<_tp*, _tp*, __true_type>
      ::copy(__first, __last, __result);
  }
};
template 
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::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 
inline _bi2 copy_backward(_bi1 __first, _bi1 __last, _bi2 __result) {
  return __copy_backward(__first, __last, __result,
                         __iterator_category(__first),
                         __distance_type(__first));
}
#endif