当前位置: 移动技术网 > IT编程>开发语言>C/C++ > STL算法_基本算法篇

STL算法_基本算法篇

2018年09月22日  | 移动技术网IT编程  | 我要评论

尼克 胡哲,钓鱼翁网,max脚本

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

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网