C++程序员应了解的那些事(32)STL 源码剖析-算法stl_numeric.h

<1>accumulate
描述:计算 init 和 [first, last) 内所有元素的总和
源码:
//version1-普通操作版本
template <class InputIterator, class T>
T accumulate(InputIterator first, InputIterator last, T init) {
  for ( ; first != last; ++first)
       init = init + *first;
  return init;
}
//version2-泛化操作版本
template <class InputIterator, class T, class BinaryOperation>
T accumulate(InputIterator first, InputIterator last, T init,BinaryOperation binary_op) {
  for ( ; first != last; ++first)
       init = binary_op(init, *first);
  return init;
}
示例:
int main()
{
  int A[] = {1, 2, 3, 4, 5};
  const int N = sizeof(A) / sizeof(int);
 
  cout << "The sum of all elements in A is " 
       << accumulate(A, A + N, 0) // 15
       << endl;
 
  cout << "The product of all elements in A is "
       << accumulate(A, A + N, 1, multiplies<int>()) //120
       << endl;
}
<2>partial_sum
描述:计算局部总和
源码:
//version1-普通操作版本
template <class InputIterator, class OutputIterator, class T>
OutputIterator __partial_sum(InputIterator first, InputIterator last,OutputIterator result, T*) {
  T value = *first;
  while (++first != last) {
    value = value + *first;
    *++result = value;
  }
  return ++result;
}

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));
}
//version2-泛化操作版本
template <class InputIterator, class OutputIterator, class T,class BinaryOperation>
OutputIterator __partial_sum(InputIterator first, InputIterator last,
                             OutputIterator result, T*,
                             BinaryOperation binary_op) {
  T value = *first;
  while (++first != last) {
    value = binary_op(value, *first);
    *++result = value;
  }
  return ++result;
}
template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator partial_sum(InputIterator first, InputIterator last,
                           OutputIterator result,
                           BinaryOperation binary_op) {
  if (first == last) return result;
  *result = *first;
  return __partial_sum(first, last, result, value_type(first), binary_op);
}
示例:
int main()
{
    const int N = 10;
    int A[N];

    fill(A, A+N, 1);
    cout << "A:                 ";
    copy(A, A+N, ostream_iterator<int>(cout, " ")); // 1 2 3 4 5 6 7 8 9 10
    cout << endl; 

    cout << "Partial sums of A: ";
    partial_sum(A, A+N, ostream_iterator<int>(cout, " ")); // 1 3 6 10 15 21 28 36 45 55
    cout << endl;
}  
<3>adjacent_difference
描述:计算[first, last) 相邻元素的差额
源码:
//version1-普通操作版本
template <class InputIterator, class OutputIterator, class T>
OutputIterator __adjacent_difference(InputIterator first, InputIterator last, 
                                     OutputIterator result, T*) {
  T value = *first;
  while (++first != last) {
    T 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));
}
//version2-泛化操作版本
template <class InputIterator, class OutputIterator, class T, 
          class BinaryOperation>
OutputIterator __adjacent_difference(InputIterator first, InputIterator last, 
                                     OutputIterator result, T*,
                                     BinaryOperation binary_op) {
  T value = *first;
  while (++first != last) {
    T tmp = *first;
    *++result = binary_op(tmp, value);
    value = tmp;
  }
  return ++result;
}
template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator adjacent_difference(InputIterator first, InputIterator last,
                                   OutputIterator result,
                                   BinaryOperation binary_op) {
  if (first == last) return result;
  *result = *first;
  return __adjacent_difference(first, last, result, value_type(first),
                               binary_op);
}
示例:
int main()
{
    int A[] = {1, 4, 9, 16, 25, 36, 49, 64, 81, 100};
    const int N = sizeof(A) / sizeof(int);
    int B[N];

    cout << "A[]:         ";
    copy(A, A + N, ostream_iterator<int>(cout, " ")); //1 4 9 16 25 36 49 64 81 100
    cout << endl;

    adjacent_difference(A, A + N, B);
    cout << "Differences: ";
    copy(B, B + N, ostream_iterator<int>(cout, " ")); // 1 3 5 7 9 11 13 15 17 19
    cout << endl;

    cout << "Reconstruct: ";
    partial_sum(B, B + N, ostream_iterator<int>(cout, " ")); //1 4 9 16 25 36 49 64 81 100
    cout << endl;
}
<4>power 
描述:计算某数的 n 幂次方,SGI 专属,不在STL标准中
源码:
// Returns x ** n, where n >= 0.  Note that "multiplication"
// is required to be associative, but not necessarily commutative. 
template <class T, class Integer, class MonoidOperation>
T power(T x, Integer n, MonoidOperation op) { //这里用的是 Russian Peasant Algorithm
  if (n == 0)
    return identity_element(op);
  else {
    while ((n & 1) == 0) {
      n >>= 1;
      x = op(x, x);
    }
 
    T result = x;
    n >>= 1;
    while (n != 0) {
      x = op(x, x);
      if ((n & 1) != 0)
        result = op(result, x);
      n >>= 1;
    }
    return result;
  }
}
 
template <class T, class Integer>
inline T power(T x, Integer n) {
  return power(x, n, multiplies<T>());
}
示例:
int main() 
{
  cout << "2 ** 30 = " << power(2, 30) << endl;//编译不通过。说找不到标识符 power ,我已经 include 了 <numeric> 
}
<5>iota
描述:设定某个区间的内容,使其内的每一个元素从指定的value值开始,呈现递增状态
源码:
template <class ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T value) {
  while (first != last) *first++ = value++;
}
示例:
int main()
{
    vector<int> V(10);     
    iota(V.begin(), V.end(), 7);
    copy(V.begin(), V.end(), ostream_iterator<int>(cout, " ")); // 7 8 9 10 11 12 13 14 15 16
    cout << endl; 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值