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源码
- STL算法_基本算法篇
- STL算法_基本算法篇
- STL算法_数值算法篇
- STL基本算法
- stl常用算法_算法和生成
- stl常用算法_查找相关
- stl常用算法_排序相关
- stl常用算法_集合运算
- 常用STL算法1_遍历
- 常用STL算法2_查找
- 常用STL算法3_排序
- 常用STL算法6_集合
- STL算法_heap算法篇
- STL算法_sort算法篇
- C++ STL源码学习(基本算法篇)
- STL源码剖析学习之基本算法
- STL---基本算法---<stl_algobase.h>概述
- 总结STL的通用算法基本形式
- Git的常用命令
- Android图片的时分秒倒计时
- 绘制B样条曲线
- hdu 5412 CRB and Queries(动态求区间第k小+整体二分)
- javasavacript 递归优化,递归变while
- STL算法_基本算法篇
- POJ 1009--Edge Detection
- 不同Json api生成json数据格式的区别
- C经典 关于一维数组指针
- HDU-4712-Hamming Distance(水随机数)
- hdu 5289 Assignment(尺取)
- VB.NET版机房收费系统之组合查询
- 对称平方数
- int **p