程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> STL算法_基本算法篇

STL算法_基本算法篇

編輯:關於C++

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

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved