前言:
此类算法都是在容器内进行数值计算的算法,常用在顺序容器上,向vector容器,数组等等。像我们平时如果要求容器内元素的总和,或者是两两之差,之和,之积等等,那肯定是自己写个for循环,但是STL库有这么方便的算法,那我们肯定用方便的玩意啦。
分为两类,第一类是用于单个容器算法,比如:accumulate,adjacent_difference,partial_sum:第二类是用于两个容器的算法,比如:inner_product
这些算法都必须写上头文件:#include < numeric >
accumulate
accumulate函数接受三个参数,前两个指出了需要求和的元素的范围,第三个参数是和的初值,第四个参数是自己写的自定义二元函数。默认情况下是对容器内元素进行累加。
//sum (1)
template <class InputIterator, class T>
T accumulate (InputIterator first, InputIterator last, T init);
//custom (2)
template <class InputIterator, class T, class BinaryOperation>
T accumulate (InputIterator first, InputIterator last, T init,
BinaryOperation binary_op);
//源码
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;
}
举个例子:
// accumulate example
#include <iostream> // std::cout
#include <functional> // std::minus
#include <numeric> // std::accumulate
int myfunction (int x, int y) {return x+2*y;}
struct myclass {
int operator()(int x, int y) {return x+3*y;}
} myobject;
int main () {
int init = 100;
int numbers[] = {10,20,30};
std::cout << "using default accumulate: ";
std::cout << std::accumulate(numbers,numbers+3,init);
std::cout << '\n';
std::cout << "using functional's minus: ";
std::cout << std::accumulate (numbers, numbers+3, init, std::minus<int>());
std::cout << '\n';
std::cout << "using custom function: ";
std::cout << std::accumulate (numbers, numbers+3, init, myfunction);
std::cout << '\n';
std::cout << "using custom object: ";
std::cout << std::accumulate (numbers, numbers+3, init, myobject);
std::cout << '\n';
return 0;
}
adjacent_difference
adjacent_difference是 STL 算法组件中的算法。adjacent_difference 的作用:计算返回相邻元素的差值(默认情况下),也可以自己写自定义二元函数去执行操作。从源码上也可以看出,目的容器可以是原来的容器,即adjacent_difference(q.begin(),q.end(),q.begin());
//difference (1)
template <class InputIterator, class OutputIterator>
OutputIterator adjacent_difference (InputIterator first, InputIterator last,
OutputIterator result);
//custom (2)
template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator adjacent_difference ( InputIterator first, InputIterator last,
OutputIterator result, BinaryOperation binary_op );
//源码
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;
}
举个例子:
// adjacent_difference example
#include <iostream> // std::cout
#include <functional> // std::multiplies
#include <numeric> // std::adjacent_difference
int myop (int x, int y) {return x+y;}
int main () {
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] << ' ';
std::cout << '\n';
std::adjacent_difference (val, val+7, result, std::multiplies<int>());
std::cout << "using functional operation multiplies: ";
for (int i=0; i<7; i++) std::cout << result[i] << ' ';
std::cout << '\n';
std::adjacent_difference (val, val+7, result, myop);
std::cout << "using custom function: ";
for (int i=0; i<7; i++) std::cout << result[i] << ' ';
std::cout << '\n';
return 0;
}
partial_sum
这个的话最大的用处就是前缀和,也可以用于局部的前缀和,不过一般我们都用来做整个容器元素的前缀和,同样也可以自己定义二元函数。
//头文件
# include <numeric>
//sum (1)
template <class InputIterator, class OutputIterator>
OutputIterator partial_sum (InputIterator first, InputIterator last,
OutputIterator result);
//custom (2)
template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator partial_sum (InputIterator first, InputIterator last,
OutputIterator result, BinaryOperation binary_op);
//源码
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;
}
举个例子:
// partial_sum example
#include <iostream> // std::cout
#include <functional> // std::multiplies
#include <numeric> // std::partial_sum
int myop (int x, int y) {return x+y+1;}
int main () {
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] << ' ';
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] << ' ';
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] << ' ';
std::cout << '\n';
return 0;
}
inner_product
//sum/multiply (1)
template <class InputIterator1, class InputIterator2, class T>
T inner_product (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, T init);
//custom (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);
//源码
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;
}
下面具体分析这个算法
函数原型:
函数1: inner_product(beg1, end1, beg2, init)
函数2: inner_product(beg1, end1, beg2, init, BinOp1, BinOp2)
函数介绍:
返回作为两个序列乘积而生成的元素的总和。步调一致地检查两个序列,将
来自两个序列的元素相乘,将相乘的结果求和。由 init 指定和的初值。假定从
beg2 开始的第二个序列具有至少与第一个序列一样多的元素,忽略第二个序列
中超出第一个序列长度的任何元素。init 的类型决定返回类型。
函数1: inner_product(beg1, end1, beg2, init)
使用元素的乘操作符(*)和加操作符(+)。
如:给定两个序列 2,3,5,8和 1,2,3,4,5,6,7,结果是初值加上下面的乘积对:
return initial_value + (2 * 1) + (3 * 2) + (5 * 3) + (8 * 4) // 如果提供初值 0,则结果是 55。
函数2:应用指定的二元操作,使用第一个操作代替加而第二个操作代替乘。
如:给定两个序列 2,3,5,8和 1,2,3,4,5,6,7
结果是:initial * 2 + 1 * 3 + 2 * 5 + 3 * 8 + 4 //即使加变乘,乘变加
举个例子:
// inner_product example
#include <iostream> // std::cout
#include <functional> // std::minus, std::divides
#include <numeric> // std::inner_product
int myaccumulator (int x, int y) {return x-y;}
int myproduct (int x, int y) {return x+y;}
int main () {
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);
std::cout << '\n';
std::cout << "using functional operations: ";
std::cout << std::inner_product(series1,series1+3,series2,init,
std::minus<int>(),std::divides<int>());
std::cout << '\n';
std::cout << "using custom functions: ";
std::cout << std::inner_product(series1,series1+3,series2,init,
myaccumulator,myproduct);
std::cout << '\n';
return 0;
}