STL 源码剖析 stl_numeric.h

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie

描述、源码、示例

version 1:普通操作版本

version 2: 泛化操作版本

1.accumulate

描述:计算 init 和 [first, last) 内所有元素的总和

源码:

//version 1
template <class InputIterator, class T>
T accumulate(InputIterator first, InputIterator last, T init) {
  for ( ; first != last; ++first)
    init = init + *first;
  return init;
}

//version 2
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.inner_product

描述:计算[first1, last1) 和 [first2, first2 + (last1 - first1)) 的内积

源码:

//version 1
template <class InputIterator1, class InputIterator2, class T>
T inner_product(InputIterator1 first1, InputIterator1 last1,
                InputIterator2 first2, T init) {
  for ( ; first1 != last1; ++first1, ++first2)
    init = init + (*first1 * *first2);
  return init;
}

//version 2
template <class InputIterator1, class InputIterator2, class T,
          class BinaryOperation1, class BinaryOperation2>
T inner_product(InputIterator1 first1, InputIterator1 last1,
                InputIterator2 first2, T init, BinaryOperation1 binary_op1,
                BinaryOperation2 binary_op2) {
  for ( ; first1 != last1; ++first1, ++first2)
    init = binary_op1(init, binary_op2(*first1, *first2));
  return init;
}

示例:

int main()
{
  int A1[] = {1, 2, 3};
  int A2[] = {4, 1, -2};
  const int N1 = sizeof(A1) / sizeof(int);

  cout << "The inner product of A1 and A2 is "
       << inner_product(A1, A1 + N1, A2, 0) //0
       << endl;
}

3.partial_sum

描述: 计算局部总和。

源码:

//version 1
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));
}

//version 2
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;
}  

4.adjacent_difference

描述:计算[first, last) 相邻元素的差额

源码:

//version 1
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));
}

//version 2
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, " ")); // 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;
}

5.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>
}

6.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;
}

STL 源码剖析 stl_numeric.h

时间: 2024-12-22 14:41:12

STL 源码剖析 stl_numeric.h的相关文章

STL 源码剖析 stl_numeric.h -- copy

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie copy //唯一对外接口 /*-------------------------------------------------------------------------------------- * copy 函数及其重载形式 */ //完全泛化版本. template<class InputIterator, class OutputIterator> // ? 这里的 In

STL 源码剖析 stl_algobase.h

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.iter_swap 描述:将两个 ForwardIterator 所指的对象对调 源码: //version 1 template <class ForwardIterator1, class ForwardIterator2, class T> inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*) {

《STL源码剖析》---stl_numeric.h阅读笔记

stl_numeric.h里面的都是数值算法,与数值计算有关. G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_numeric.h 完整列表 /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any pu

《STL源码剖析》---stl_pair.h阅读笔记

pair是STL中的模板类型,它可以存储两个元素,它也被称作"对组".在map中已经用到了它,pair其实就是一个struct结构,存有两个public的元素,重载了几个运算符,没有什么成员函数,源代码很简单. G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_pair.h 完整列表 /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy,

《STL源码剖析》---stl_tree.h阅读笔记

STL中,关联式容器的内部结构是一颗平衡二叉树,以便获得良好的搜索效率.红黑树是平衡二叉树的一种,它不像AVL树那样要求绝对平衡,降低了对旋转的要求,但是其性能并没有下降很多,它的搜索.插入.删除都能以O(nlogn)时间完成.平衡可以在一次或者两次旋转解决,是"性价比"很高的平衡二叉树. RB-tree(red black tree)红黑树是平衡二叉树.它满足一下规则 (1)每个节点不是红色就是黑色. (2)根节点是黑色. (3)如果节点为红色,则其子节点比为黑色. (4)任何一个节

《STL源码剖析》---stl_iterator.h阅读笔记

STL设计的中心思想是将容器(container)和算法(algorithm)分开,迭代器是容器(container)和算法(algorithm)之间的桥梁. 迭代器可以如下定义:提供一种方法,能够依序寻访某个容器内的所有元素,而又无需暴露该容器的内部表达方式. 在阅读代码之前,要先了解一个新概念:Traits编程技法 template <class T> struct MyIter { typedef T value_type //内嵌型别声明 T *ptr; MyIter(T *p = 0

STL 源码剖析 算法 stl_algo.h -- search_n

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search_n ---------------------------------------------------------------------------------------- 描述:在序列[first, last) 所涵盖的区间中,查找"连续 count 个符合条件之元素"所形成的子序列, 并返回迭代器 last 思路: 1.首先找出 value 第一次出现点

STL 源码剖析 算法 stl_algo.h -- lower_bound

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie lower_bound(应用于有序区间) -------------------------------------------------------------------------------------------------------------------------- 描述:二分查找,返回一个迭代器指向每一个"不小于 value "的元素, 或 value 应该

STL 源码剖析 算法 stl_algo.h -- upper_bound

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie upper_bound(应用于有序区间) ------------------------------------------------------------------------------------------------------------------------------------------------- 描述:受STL区间前闭后开习惯的影响,upper_boun