SGI STL算法
数值算法(Numeric)
使用需包含文件<numeric>
Accumulate函数
功能:计算init和[first,last)内所有元素的总和,需要提供一个初始值init
使用:
Int ia[5] = {1,2,3,4,5};
Vector<int> iv(ia, ia+5);
Accumulate(iv.begin(), iv.end(), 0);
//15, 0+1+2+3+4+5
Accumulate(iv.begin(), iv.end(), 0, minux<int>());
//-15, 0-1-2-3-4-5
源码:
//版本1
template <class _InputIterator, class _Tp>
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
{
for ( ; __first != __last; ++__first)
__init = __init + *__first;
return __init;
}
//版本2
template <class _InputIterator, class _Tp, class _BinaryOperation>
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
_BinaryOperation __binary_op)
{
for ( ; __first != __last; ++__first)
__init = __binary_op(__init, *__first);
return __init;
}
Inner_product函数
功能:算法计算[first1,last1)和[first2,last2)的内积,需要提供初始值init
使用:
Int ia[5] = {1,2,3,4,5};
Vector<int> iv(ia, ia+5);
Inner_product(iv.begin(), iv.end(), iv.begin(), 10);
//65, 10+1*1+2*2+3*3+4*4+5*5
Inner_product(iv.begin(), iv.end(), iv.begin(), 10, minus<int>(), plus<int>());
//-20, 10-1+1-2+2-3+3-4+4-5+5
源码:
template <class _InputIterator1, class _InputIterator2, class _Tp>
_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _Tp __init)
{
for ( ; __first1 != __last1; ++__first1, ++__first2)
__init = __init + (*__first1 * *__first2);
return __init;
}
//执行二元操作符
template <class _InputIterator1, class _InputIterator2, class _Tp,
class _BinaryOperation1, class _BinaryOperation2>
_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _Tp __init,
_BinaryOperation1 __binary_op1,
_BinaryOperation2 __binary_op2)
{
for ( ; __first1 != __last1; ++__first1, ++__first2)
__init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
return __init;
}
Partial_sum函数
功能:算法partial_sum用来计算局部总和,它会将*first赋值给result,将*first和*(first+1)是和赋值给*(result+1)依此类推。
用法:
Int ia[5] = {1,2,3,4,5};
Vector<int> iv(ia, ia+5);
//迭代器绑定到cout,作为输出
Ostream_iterator<int> oite(cout, “”);
Partial_sum(iv.begin(), iv.end(), oite);
//1 3 6 10 15(第n个新元素是前n个旧元素的相加总计)
Partial_sum(iv.begin(), iv.end(), oite, minus<int>());
//1 -1 -4 -8 -13(第n个新元素是前n个旧元素的运算总计)
源码:
template <class _InputIterator, class _OutputIterator, class _Tp>
_OutputIterator
__partial_sum(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Tp*)
{
_Tp __value = *__first;
while (++__first != __last) {
__value = __value + *__first;
*++__result = __value;
}
return ++__result;
}
//将first的第一个值赋予个result的第一个值中,并且萃取出first的值类型
template <class _InputIterator, class _OutputIterator>
_OutputIterator
partial_sum(_InputIterator __first, _InputIterator __last,
_OutputIterator __result)
{
if (__first == __last) return __result;
*__result = *__first;
return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first));
}
Adjacent_difference函数
功能:算法用来计算[first,last)中相邻元素的差额
用法:
Int ia[5] = {1,2,3,4,5};
Vector<int> iv(ia, ia+5);
Adjacent_difference(iv.begin(), iv.end(), oite);
//1 1 1 1 1(#1元素照旧,#n新元素等于#n旧元素-#n-1旧元素)
Adjacent_difference(iv.begin(), iv.end(), oite, plus<int>());
//1 3 5 7 9(#1元素照旧,#n新元素等于op(#n旧元素, #n-1旧元素))
源码:
template <class _InputIterator, class _OutputIterator, class _Tp>
_OutputIterator
__adjacent_difference(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Tp*)
{
_Tp __value = *__first;
while (++__first != __last) {
_Tp __tmp = *__first;
*++__result = __tmp - __value;
__value = __tmp;
}
return ++__result;
}
template <class _InputIterator, class _OutputIterator>
_OutputIterator
adjacent_difference(_InputIterator __first,
_InputIterator __last, _OutputIterator __result)
{
if (__first == __last) return __result;
*__result = *__first;
return __adjacent_difference(__first, __last, __result,
__VALUE_TYPE(__first));
}
*Power函数
功能:函数为SGI专属,用来计算某数的n幂次方。这里指自己对自己进行某种运算,达n次,运算类型可由外界指定,如果指定为乘法,那就是乘幂。
用法:
Power(10, 3);//1000, 10*10*10
Power(10, 3, plus<int>());//30, 10+10+10
源码:
//注意:MonoidOperation必须满足结合律associative,但不满足交换律commutative。
template <class _Tp, class _Integer, class _MonoidOperation>
_Tp __power(_Tp __x, _Integer __n, _MonoidOperation __opr)
{
if (__n == 0)
return identity_element(__opr);
else {
while ((__n & 1) == 0) {
__n >>= 1;
__x = __opr(__x, __x);
}
_Tp __result = __x;
__n >>= 1;
while (__n != 0) {
__x = __opr(__x, __x);
if ((__n & 1) != 0)
__result = __opr(__result, __x);
__n >>= 1;
}
return __result;
}
}
//版本二,以multiplies<_Tp>()操作调用版本一
template <class _Tp, class _Integer>
inline _Tp __power(_Tp __x, _Integer __n)
{
return __power(__x, __n, multiplies<_Tp>());
}
*Itoa函数
功能:函数为SGI专属,用来设定某个区间的内容,使其每个元素从指定值value开始,呈现递增
源码:
//在 [first,last) 范围内內填入value, value+1, value+2...
template <class _ForwardIter, class _Tp>
void
iota(_ForwardIter __first, _ForwardIter __last, _Tp __value)
{
while (__first != __last)
*__first++ = __value++;
}
基本算法Algobase
Equal函数
功能:如果两个序列在[first,last)区间内相等,equal返回true,如果第二序列的元素比较多,多出来的元素不予考虑。因此,如果判断两个序列完全相等,必须先判断其元素个数是否相同。如果第二序列元素比第一序列少,则会造成不可预测的结果。
使用:
Int ia[9] = {0,1,2,3,4,5,6,7,8};
Vector<int> iv1(ia, ia+5);
Vector<int> iv2(ia, ia+9);
Equal(iv1.begin(), iv1.end(), iv2.begin()); //1,true
Equal(iv1.begin(), iv1.end(), &ia[3]); //0,false
//{0.1.2.3.4}小于{3,4,5,6,7}
源码:
//版本1
template <class _InputIter1, class _InputIter2>
inline bool equal(_InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2) {
for ( ; __first1 != __last1; ++__first1, ++__first2)
if (*__first1 != *__first2)
return false;
return true;
}
//版本2
template <class _InputIter1, class _InputIter2, class _BinaryPredicate>
inline bool equal(_InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2, _BinaryPredicate __binary_pred) {
for ( ; __first1 != __last1; ++__first1, ++__first2)
if (!__binary_pred(*__first1, *__first2))
return false;
return true;
}
Fill函数
功能:将[first,last)内的所有元素改填新值
使用:
Int ia[9] = {0,1,2,3,4,5,6,7,8};
Vector<int> iv1(ia, ia+5);
Fill(iv1.begin(0, iv1.end(), 9);
//区间内全部置9 //9 9 9 9 9
源码:
template <class _ForwardIter, class _Tp>
void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) {
for ( ; __first != __last; ++__first)
*__first = __value;
}
Fill_n函数
功能:将[first,last)内的前n个元素改填新值
使用:
Int ia[9] = {0,1,2,3,4,5,6,7,8};
Vector<int> iv1(ia, ia+5);
Fill_n(iv1.begin(), 3, 7); //从迭代器所指位置开始,填3个7
//7 7 7 3 4
如果n超越了容器的现有大小,由于每次迭代进行的是assignment操作,是一种overwrite操作,所以一旦操作区间超越了容器大小,就会造成不可预期的结果。解决办法之一是利用inserter()产生一个具有插入而非overwrite能力的迭代器,用法如下
Int ia[3] = {0,1,2};
Fill_n(inserter(iv, iv.begin(), 5, 7));
源码:
template <class _OutputIter, class _Size, class _Tp>
_OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __value) {
for ( ; __n > 0; --__n, ++__first)
*__first = __value;
return __first;
}
Iter_swap函数
功能:将两个ForwardIterators所指的对象对调
源码:
template <class _ForwardIter1, class _ForwardIter2>
inline void iter_swap(_ForwardIter1 __a, _ForwardIter2 __b) {
__iter_swap(__a, __b, __VALUE_TYPE(__a));
}
template <class _ForwardIter1, class _ForwardIter2, class _Tp>
inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) {
_Tp __tmp = *__a;
*__a = *__b;
*__b = __tmp;
}
Lexicographical_compare函数
功能:以字典排列方式对两个序列[first1,last1)和[first2,last2)进行比较。对两个序列中对应位置上的元素进行比较,并持续到
- 某一组对应元素彼此不相等
同时达到last1和last2,两序列大小相同
到达last1或last2,两序列大小不同
如果出现*first1 < *first2,则返回true
如果出现*first2 < *first1,则返回false
如果直到循环结束,两个序列的值都相等
如果第一个序列比第二个序列短,则返回true
否则返回false(两个序列长度相等也返回false)
使用:
String stra1[] = {“Jamie”, “JJHou”, “Jason”};
String stra2[] = {“Jamie”, “JJhou”, “Jerry”};
Lexicographical_compare(stra1, stra+2, stra2, stra+2);
//1 (stra1小于stra2)
Lexicographical_compare(stra1, stra1+2, stra2, stra2+2, greater<string>());
//0 (stra1不大于stra2)
源码:
//版本1
template <class _InputIter1, class _InputIter2>
bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2, _InputIter2 __last2) {
for ( ; __first1 != __last1 && __first2 != __last2
; ++__first1, ++__first2) {
if (*__first1 < *__first2)
return true;
if (*__first2 < *__first1)
return false;
}
return __first1 == __last1 && __first2 != __last2;
}
//版本2
template <class _InputIter1, class _InputIter2, class _Compare>
bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2, _InputIter2 __last2,
_Compare __comp) {
for ( ; __first1 != __last1 && __first2 != __last2
; ++__first1, ++__first2) {
if (__comp(*__first1, *__first2))
return true;
if (__comp(*__first2, *__first1))
return false;
}
return __first1 == __last1 && __first2 != __last2;
}
//const unsigned char*原生指针特化版本
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));
return __result != 0 ? __result < 0 : __len1 < __len2;
}
//const signed char*原生指针特化版本
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 */
}
Max函数
功能:取两个对象中的较大值,版本2使用仿函数comp来判断大小
源码:
template <class _Tp>
inline const _Tp& max(const _Tp& __a, const _Tp& __b) {
return __a < __b ? __b : __a;
}
template <class _Tp, class _Compare>
inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) {
return __comp(__a, __b) ? __b : __a;
}
Min函数
功能:取两个对象中较小值,版本2使用仿函数comp来判断大小。
源码:
template <class _Tp>
inline const _Tp& min(const _Tp& __a, const _Tp& __b) {
return __b < __a ? __b : __a;
}
template <class _Tp, class _Compare>
inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) {
return __comp(__b, __a) ? __b : __a;
}
Swap函数
功能:交换a和b的值
源码:
// template <class _Tp>
inline void swap(_Tp& __a, _Tp& __b) {
_Tp __tmp = __a;
__a = __b;
__b = __tmp;
}
Mismatch函数
功能:用来比较两个序列,指出两者之间的第一个不匹配点,返回一对迭代器分别指向两序列中的不匹配点。如果第二序列的元素比第一序列多,多出来的元素忽略不计,如果第二序列的元素个数比第一序列少,会发生不可预期的行为。
使用:
Int ia[9] = {0,1,2,3,4,5,6,7,8};
Vector<int> iv1(ia, ia+5);
Vector<int> iv2(ia, ia+9);
*(mismatch(iv1.begin(), iv1.end(), iv2.begin()).first); //?
*(mismatch(iv1.begin(), iv1.end(), iv2.begin()).second); //5
//判断两个区间的第一个不匹配点,返回右两个迭代器组成的pair,上述应先判断迭代器是否不等于容器的end(),然后才可以做输出操作。
源码:
template <class _InputIter1, class _InputIter2>
pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1,
_InputIter1 __last1,
_InputIter2 __first2) {
while (__first1 != __last1 && *__first1 == *__first2) {
++__first1;
++__first2;
}
return pair<_InputIter1, _InputIter2>(__first1, __first2);
}
template <class _InputIte