STL算法

算法:以有限的步骤,解决逻辑或者数学上的问题。

  • 特定的算法往往搭配特定的数据结构,特定的数据结构是为了实现某种特定的算法。
  • 关联式容器:与特定数据结构相关的算法。
  • 泛型:不依赖于具体类型,由模板实现。
  • 算法的泛型化:把操作对象的型别加以抽象化,把操作对象的标示法和取间目标的移动行为抽象化,整个算法就能在一个抽象层面上工作了。
  • 泛型的算法可以不依赖于容器的具体类型,使得算法能作用于不同类型的容器上,实现代码复用。
  • 迭代器是一种行为类似指针的对象,也可视为一种智能指针。
  • 迭代器作为一种访问容器中元素的方式,具有相对统一的接口,是一种对容器元素访问的抽象。
  • 算法通过迭代器提供的功能,实现对容器中元素的操作,而无需考虑容器的具体细节。使得算法无需依赖特定容器,降低算法与容器间的耦合,两者间关系如下图。
graph LR algorithm --iterator--> containers containers --- vector containers --- array containers --- list containers --- ... containers --- deque containers --- set containers --- map

STL算法主要分为以下几类:

  • 数值算法 numeric
  • 基础算法 algobase
  • 集合相关算法 set
  • 堆算法 heap
  • 数据处理算法

数值算法 numeric

累加元素

  1. 将[__first,__last)范围内的元素累加起来,起始值为__init
template <class _InputIterator, class _Tp>
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
{
  __STL_REQUIRES(_InputIterator, _InputIterator);
  for ( ; __first != __last; ++__first)
    __init = __init + *__first;
  return __init;
}
  1. 将[__first,__last)范围内的元素累加起来,起始值为__init,累加操作仿函数类由用户指定
template <class _InputIterator, class _Tp, class _BinaryOperation>
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
               _BinaryOperation __binary_op)

相邻元素差

  1. 计算[__first,__last)范围内相邻元素的差,并将结果依次输出到输出迭代器。
template <class _InputIterator, class _OutputIterator>
_OutputIterator
adjacent_difference(_InputIterator __first,
                    _InputIterator __last, _OutputIterator __result)
  1. 指定对相邻元素进行操作的版本
template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
_OutputIterator 
adjacent_difference(_InputIterator __first, _InputIterator __last,
                    _OutputIterator __result, _BinaryOperation __binary_op)

向量内积

  1. 计算两个向量对应元素乘积之和
template <class _InputIterator1, class _InputIterator2, class _Tp>
_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
                  _InputIterator2 __first2, _Tp __init)
  1. 指定向量对应元素间进行的操作的版本
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)

部分和

  1. 计算向量中[__first,__last)范围内元素的和
template <class _InputIterator, class _OutputIterator>
_OutputIterator 
partial_sum(_InputIterator __first, _InputIterator __last,
            _OutputIterator __result)
  1. 指定操作版本
template <class _InputIterator, class _OutputIterator, class _Tp,
          class _BinaryOperation>
_OutputIterator 
__partial_sum(_InputIterator __first, _InputIterator __last, 
              _OutputIterator __result, _Tp*, _BinaryOperation __binary_op)

递增填充
向向量[__first,__last)范围内依次填充元素,元素的起始值为__value

template <class _ForwardIter, class _Tp>
void 
iota(_ForwardIter __first, _ForwardIter __last, _Tp __value)
{
  while (__first != __last)
    *__first++ = __value++;
}

次方

1.默认进行的乘方操作。

template <class _Tp, class _Integer>
inline _Tp power(_Tp __x, _Integer __n)
{
  return __power(__x, __n);
}

函数中调用内部函数__power,并调用stl_function中定义的multiplies二元仿函数

template <class _Tp, class _Integer>
inline _Tp __power(_Tp __x, _Integer __n)
{
  return __power(__x, __n, multiplies<_Tp>());
}

2.可指定操作方法的版本:

template <class _Tp, class _Integer, class _MonoidOperation>
inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __opr)
{
  return __power(__x, __n, __opr);
}

在该函数调用内部函数__power,定义如下:
对值__x重复进行__n次__opr操作。以下函数中对次方的计算方法是,按__n的二进制表示对__x进行次方运算(类似与快速幂的原理)。

template <class _Tp, class _Integer, class _MonoidOperation>
_Tp __power(_Tp __x, _Integer __n, _MonoidOperation __opr)
{
  if (__n == 0)        //被操作元素为零,平凡情况
    return identity_element(__opr);    //返回平凡值0
  else {               //非平凡情况
    while ((__n & 1) == 0) {    //__n为偶数
      __n >>= 1;                //__n/=2
      __x = __opr(__x, __x);    //进行两次操作
    }

    _Tp __result = __x;        //保存上面操作得到的结果
    __n >>= 1;                 //__n/=2
    while (__n != 0) {         //还有剩余操作
      __x = __opr(__x, __x);   //进行两次操作
      if ((__n & 1) != 0)      //__n为奇数
        __result = __opr(__result, __x);//进行依次操作
      __n >>= 1;               //__n/=2
    }
    return __result;
  }
}
posted @ 2019-11-26 17:16  技术狂人djc  阅读(320)  评论(0编辑  收藏  举报