C++/C++11中头文件numeric的使用

<numeric>是C++标准程序库中的一个头文件,定义了C++ STL标准中的基础性的数值算法(均为函数模板):

(1)、accumulate: 以init为初值,对迭代器给出的值序列做累加,返回累加结果值,值类型必须支持”+”算符。它还有一个重载形式。

(2)、adjacent_difference:对输入序列,计算相邻两项的差值,写入到输出序列中。它还有一个重载形式。

(3)、inner_product:计算两个输入序列的内积。它还有一个重载形式。

(4)、partial_sum:计算输入序列从开始位置到当前位置的累加值,写入输出序列中。它还有一个重载形式。

(5)、iota: 向序列中写入以val为初值的连续值序列。

The algorithms are similar to the Standard Template Library (STL) algorithms and are fully compatible with the STL but are part of the C++ Standard Library rather than the STL. Like the STL algorithms, they are generic because they can operate on a variety of data structures. The data structures that they can operate on include STL container classes, such as vector and list, and program-defined data structures and arrays of elements that satisfy the requirements of a particular algorithm. The algorithms achieve this level of generality by accessing and traversing the elements of a container indirectly through iterators. The algorithms process iterator ranges that are typically specified by their beginning or ending positions. The ranges referred to must be valid in the sense that all pointers in the ranges must be dereferenceable and within the sequences of each range, the last position must be reachable from the first by means of incrementation.

下面是从其它文章中copy的<numeric>测试代码,详细内容介绍可以参考对应的reference:

 

#include "numeric.hpp"
#include <iostream>
#include <functional>
#include <numeric>

// reference: http://www.cplusplus.com/reference/numeric/

namespace numeric_ {


/*
std::accumulate: The behavior of this function template is equivalent to :
template <class InputIterator, class T>
T accumulate (InputIterator first, InputIterator last, T init)
{
	while (first!=last) {
		init = init + *first;  // or: init=binary_op(init,*first) for the binary_op version
		++first;
	}
	return init;
}
*/

static int myfunction(int x, int y) { return x + 2 * y; }

struct myclass {
	int operator()(int x, int y) { return x + 3 * y; }
} myobject;

int test_numeric_accumulate()
{
	int init = 100;
	int numbers[] = { 10, 20, 30 };

	std::cout << "using default accumulate: ";
	std::cout << std::accumulate(numbers, numbers + 3, init); // 160
	std::cout << '\n';

	std::cout << "using functional's minus: ";
	std::cout << std::accumulate(numbers, numbers + 3, init, std::minus<int>()); // 40 std::minus => x - y
	std::cout << '\n';

	std::cout << "using custom function: ";
	std::cout << std::accumulate(numbers, numbers + 3, init, myfunction); // 220
	std::cout << '\n';

	std::cout << "using custom object: ";
	std::cout << std::accumulate(numbers, numbers + 3, init, myobject); // 280
	std::cout << '\n';

	return 0;
}

///
/*
std::adjacent_difference: The behavior of this function template is equivalent to
template <class InputIterator, class OutputIterator>
OutputIterator adjacent_difference (InputIterator first, InputIterator last, OutputIterator result)
{
	if (first!=last) {
		typename iterator_traits<InputIterator>::value_type val,prev;
		*result = prev = *first;
		while (++first!=last) {
			val = *first;
			*++result = val - prev;  // or: *++result = binary_op(val,prev)
			prev = val;
		}
		++result;
	}
	return result;
}
*/

static int myop(int x, int y) { return x + y; }

int test_numeric_adjacent_difference()
{
	int val[] = { 1, 2, 3, 5, 9, 11, 12 };
	int result[7];

	std::adjacent_difference(val, val + 7, result);
	std::cout << "using default adjacent_difference: ";
	for (int i = 0; i<7; i++) std::cout << result[i] << ' '; // 1 1 1 2 4 2 1
	std::cout << '\n';

	std::adjacent_difference(val, val + 7, result, std::multiplies<int>()); // x * y
	std::cout << "using functional operation multiplies: ";
	for (int i = 0; i<7; i++) std::cout << result[i] << ' '; // 1 2 6 15 45 99 132
	std::cout << '\n';

	std::adjacent_difference(val, val + 7, result, myop); // 1 3 5 8 14 20 23
	std::cout << "using custom function: ";
	for (int i = 0; i<7; i++) std::cout << result[i] << ' ';
	std::cout << '\n';

	return 0;
}


/*
std::inner_product: The behavior of this function template is equivalent to:
template <class InputIterator1, class InputIterator2, class T>
T inner_product (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init)
{
	while (first1!=last1) {
		init = init + (*first1)*(*first2);
		// or: init = binary_op1 (init, binary_op2(*first1,*first2));
		++first1; ++first2;
	}
	return init;
}
*/

static int myaccumulator(int x, int y) { return x - y; }
static int myproduct(int x, int y) { return x + y; }

int test_numeric_inner_product()
{
	int init = 100;
	int series1[] = { 10, 20, 30 };
	int series2[] = { 1, 2, 3 };

	std::cout << "using default inner_product: ";
	std::cout << std::inner_product(series1, series1 + 3, series2, init); // 240
	std::cout << '\n';

	std::cout << "using functional operations: ";
	std::cout << std::inner_product(series1, series1 + 3, series2, init, 
		std::minus<int>(), std::divides<int>()); // 70
	std::cout << '\n';

	std::cout << "using custom functions: ";
	std::cout << std::inner_product(series1, series1 + 3, series2, init,
		myaccumulator, myproduct); // 34
	std::cout << '\n';

	return 0;
}

//
/*
std::partial_sum: The behavior of this function template is equivalent to:
template <class InputIterator, class OutputIterator>
OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result)
{
	if (first!=last) {
		typename iterator_traits<InputIterator>::value_type val = *first;
		*result = val;
		while (++first!=last) {
			val = val + *first;   // or: val = binary_op(val,*first)
			*++result = val;
		}
		++result;
	}
	return result;
}
*/

static int myop_(int x, int y) { return x + y + 1; }

int test_numeric_partial_sum()
{
	int val[] = { 1, 2, 3, 4, 5 };
	int result[5];

	std::partial_sum(val, val + 5, result);
	std::cout << "using default partial_sum: ";
	for (int i = 0; i<5; i++) std::cout << result[i] << ' '; // 1 3 6 10 15
	std::cout << '\n';

	std::partial_sum(val, val + 5, result, std::multiplies<int>());
	std::cout << "using functional operation multiplies: ";
	for (int i = 0; i<5; i++) std::cout << result[i] << ' '; // 1 2 6 24 120
	std::cout << '\n';

	std::partial_sum(val, val + 5, result, myop_);
	std::cout << "using custom function: ";
	for (int i = 0; i<5; i++) std::cout << result[i] << ' '; // 1 4 8 13 19
	std::cout << '\n';

	return 0;
}

///
/*
std::iota: The behavior of this function template is equivalent to:
template <class ForwardIterator, class T>
void iota (ForwardIterator first, ForwardIterator last, T val)
{
	while (first!=last) {
		*first = val;
		++first;
		++val;
	}
}
*/

int test_numeric_iota()
{
	int numbers[10];

	std::iota(numbers, numbers + 10, 100);

	std::cout << "numbers:";
	for (int& i : numbers) std::cout << ' ' << i; // 100 101 102 103 104 105 106 107 108 109
	std::cout << '\n';

	return 0;
}

} // namespace numeric_


GitHub: https://github.com/fengbingchun/Messy_Test

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值