STL 简单 <stl_numeric.h> 算法的实现

来源:互联网 发布:北京java周末班 编辑:程序博客网 时间:2024/06/10 17:42

1.简介

在STL中,算法可以大致分为两类:质变算法、非质变算法。质变算法会改变操作对象的值,非质变算法不会改变操作对象的值。所有的STL算法都作用在迭代器(iterator)所标识的区间上。

         本文介绍的数值算法包括:

1.      accumulate:计算 [ first,last ) 内所有元素的总和;

2.      adjacent_difference:计算 [ first,last ) 中相邻元素的差额;

3.      inner_product:计算 [ first1,last1 ) 和[ first2, first2 + ( last1 – first1 ) ) 的一般内积;

4.      partial_sum:计算局部总和;

5.      power:计算某数的 n 次方;

这些数值算法不会改变操作对象,所以可以归类到非质变算法中,同时,各个数值算法的实现非常简单,没有包含高技巧性的代码。

 

2.设计与实现

我用VS2013写的程序(github),数值算法的实现版本的位于cghSTL/version/cghSTL-0.5.1.rar

数组算法的实现需要以下文件:

1.    cghVector.h,自己实现的vector,位于cghSTL/sequence containers/cghVector/想了解vector实现细节的同学请移步:STL简单vector的实现

2.      cghUtil.h:算法的输出会用到pair结构体,我把pair自己实现了一遍,cghUtil.h 位于cghSTL/cghUtil/

3.    cghStl_numeric.h,本文的主角:数值算法,位于cghSTL/algorithms/

4.   test_algorithms_numeric.cpp,测试文件,位于cghSTL/test/

 

为了增强代码的可读性,我用region把各个算法隔开,如下图所示


数值算法一点不难,直接上代码吧,注释已经说明了一切~

cghStl_numeric.h

/********************************************************************  Copyright(c) 2016 Chen Gonghao*  All rights reserved.**  chengonghao@yeah.net**  文件内容:cghSTL 数值算法******************************************************************/#ifndef _CGH_STL_ALGORITHMS_NUMERIC_#define _CGH_STL_ALGORITHMS_NUMERIC_#include "cghUtil.h"namespace CGH{#pragma region accumulate/*accumulate算法用来计算 init 和 [ first, last )内所有元素的总和必须提供 init ,因为当 [ first, last )为空时仍能获得一个明确定义的值如果希望计算 [ first, last )中所有数值的总和,应该将 init 设为 0*/template<class iterator, class T>T accumulate(iterator first, iterator last, T init){for (; first != last; ++first){init = init + *first; // 将每个元素值累加到 init 上}return init;}/* binaryOp:用户指定的计算方法 */template<class iterator, class T, class binaryOp>T accumulate(iterator first, iterator last, T init, binaryOp binary_op){for (; first != last; ++first){init = binary_op(init, *first); // binary_op:特定的计算方式}return init;}#pragma endregion#pragma region ajacent_difference/*ajacent_difference 算法用来计算[ first, last ] 中相邻元素的差额*/template<class InputIterator, class OutputIterator>OutputIterator ajacent_difference(InputIterator first, InputIterator last, OutputIterator result){if (first == last){return result;}*result = *first; // 记录第一个元素iterator_traits<InputIterator>::value_type value = *first; // 利用特性萃取机取出value_type的类型while (++first != last){iterator_traits<InputIterator>::value_type tmp = *first; // 将相邻两个元素的差值赋给result*++result = tmp - value;value = tmp;}iterator_traits<InputIterator>::value_type tmp = *first;*first = *last;*last = tmp;return ++result;}template<class InputIterator, class OutputIterator, class binaryOp>OutputIterator ajacent_difference(InputIterator first, InputIterator last, OutputIterator result, binaryOp binary_op){if (first == last){return result;}*result = *first; // 记录第一个元素iterator_traits<InputIterator>::value_type value = *first; // 利用特性萃取机取出value_type的类型while (++first != last){iterator_traits<InputIterator>::value_type tmp = *first;*++result = binary_op(tmp, value); // 以用户自定义的方式计算相邻两个元素的值,并赋给resultvalue = tmp;}return ++result;}#pragma endregion#pragma region inner_product/* inner_product能够计算[ first1, last1 ] 和 [ fisrt2, first2 + ( last1 - fisrt1 ) ] 的一般内积(generalied inner product)必须提供初值,确保 [ fisrt, last ] 为空时,仍有明确定义*/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;}template<class InputIterator1, class InputIterator2, class T, class binaryOp1, class binaryOp2>T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, binaryOp1 binary_op1, binaryOp2 binary_op2){for (; first1 != last1; ++first1, ++first2){init = binary_op1(init, binary_op2(*first1, *first2)); // 根据用户自定义的函数:binary_op1、binary_op2,计算内积}return init;}#pragma endregion#pragma region partial_sum/*partial_sum用来计算局部总和,它会将 *first 赋值给 *result ,将 *first和 *(first + 1)的和赋值给 *( result + 1 ),以此类推,注意,result 可以等于 first,这使得我们得以完成就地计算。*/template<class InputIterator, class OutputIterator>OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result){if (first == last){return result;}*result = *first;iterator_traits<InputIterator>::value_type value = *first;while (++first != last){value = value + *first ; // 值的累加*++result = value ;}return ++result ;}template<class InputIterator, class OutputIterator, class binaryOp>OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result, binaryOp binary_op){if(first == last){return result;}*result = *first;iterator_traits<InputIterator>::value_type value = *first;while(++first != last){value = binary_op( value, *first ) ; // 以用户指定的方法累加值*++result = value ;}return ++result ;}#pragma endregion#pragma region power/* 计算某数的 n 次幂*/template<class T, class Integer>inline T power(T x, Integer n){return power(x, n, multiplies<T>()) ;}template<class T, class Integer, class MonoidOp>T power(T x, Integer n, MonoidOp op){while ((n & 1) == 0){n = n >> 1 ;x = op(x, x) ;}T result = x ;n = n >> 1 ;while (n != 0){x = op(x, x) ;if ((n & 1) != 0){result = op(result, x) ;}n = n >> 1 ;}return result ;}#pragma endregion}#endif


 

3.测试

测试环节的主要内容已在注释中说明

test_algorithms_numeric.cpp

/********************************************************************  Copyright(c) 2016 Chen Gonghao*  All rights reserved.**  chengonghao@yeah.net**  文件内容:cghStl_numeric.h 中的数值算法的测试******************************************************************/#include "stdafx.h"#include "cghVector.h"#include "cghStl_numeric.h"#include <iterator>using namespace::std;int _tmain(int argc, _TCHAR* argv[]){using namespace::CGH;std::cout << "创建一个vector,依次 puah_back 1、2、3、4、5" << endl << endl;cghVector<int> test;test.push_back(1);test.push_back(2);test.push_back(3);test.push_back(4);test.push_back(5);ostream_iterator<int> oite(cout, " "); // ostream_iterator<int>是一个迭代器,把ostream_iterator<int>绑定到cout,作为输出使用std::cout << "******************测试 accumulate 算法************************" << endl << endl;cout << "缺省采用plus累加:1 + 2 + 3 + 4 + 5 = ";cout << accumulate(test.begin(), test.end(), 0) << endl << endl;cout << "用户指定 minus 函数:-1 - 2 - 3 - 4 - 5 = ";cout << accumulate(test.begin(), test.end(), 0, minus<int>()) << endl << endl;std::cout << "******************测试 ajacent_difference 算法************************" << endl << endl;cout << "默认情况下,计算 1、2、3、4、5 两两之间的差值:";ajacent_difference(test.begin(), test.end(), oite);cout << endl << endl;cout << "用户指定 plus 函数,计算 1、2、3、4、5 两两之间的差值,再加 1:";ajacent_difference(test.begin(), test.end(), oite, plus<int>());cout << endl << endl;std::cout << "******************测试 inner_product 算法************************" << endl << endl;cout << "1×1 + 2×2 + 3×3 + 4×4 + 5×5 = ";cout << inner_product(test.begin(), test.end(), test.begin(), 0);cout << endl << endl;cout << "-( 1+1 ) -  ( 2+2 ) - ( 3+3 ) - ( 4+4 ) - ( 5+5 ) = ";cout << inner_product(test.begin(), test.end(), test.begin(), 0, minus<int>(), plus<int>());cout << endl << endl;std::cout << "******************测试 partial_sum 算法************************" << endl << endl;cout << "默认情况下,计算 第 n 个新元素是前 n 个旧元素的相加总计:";partial_sum(test.begin(), test.end(), oite);cout << endl << endl;cout << "用户指定 minus 函数:";partial_sum(test.begin(), test.end(), oite, minus<int>());cout << endl << endl;std::cout << "******************测试 power 算法************************" << endl << endl;cout << "默认情况下,计算 10 的 3 次方:";cout << power(10, 3) << endl ;cout << endl;cout << "用户指定 plus 函数,计算 10 + 10 + 10:";cout << power(10, 3, plus<int>()) << endl ;cout << endl;system("pause");return 0;}


 

结果如下图所示:

0 0
原创粉丝点击