数值算法
accumulate(beg,end,initValue)
accumulate(beg,end,initValue,op)
以上第一种形式计算initValue和区间[beg,end)内的所有元素的总和,更具体的说,它针对每一个元素调用以下表达式:
initValue=initValue+elem
以上第二种形式计算initValue和区间[beg,end)内每一个元素进行op运算的结果,更具体的说,它针对每一个元素调用如下表达式:
initValue=op(initValue,elem)
如果序列为空(beg==end),则两者都返回initValue。
代码示例:
//fuzhu.h 以下都会用到
#ifndef FUZHU_H
#define FUZHU_H
#include<iostream>
#include<vector>
#include<map>
#include<list>
#include<set>
#include<deque>
#include<string>
#include<algorithm>
#include<functional>
#include<iterator>
#include<numeric>
template<class T>
inline void PRINT_ELEMENTS(const T& coll,const char* optcstr="")
{
typename T::const_iterator pos;
std::cout<<optcstr;
for(pos=coll.begin();pos!=coll.end();++pos)
{
std::cout<<*pos<<" ";
}
std::cout<<std::endl;
}
template<class T>
inline void INSERT_ELEMENTS(T& coll,int first,int last)
{
for(int i=first;i<=last;i++)
{
coll.insert(coll.end(),i);
}
}
void print(int elem)
{
std::cout<<elem<<" ";
}
#endif
#include"fuzhu.h"
using namespace std;
int main()
{
vector<int> coll;
INSERT_ELEMENTS(coll,1,9);
PRINT_ELEMENTS(coll);
//0+1+2+...+9
cout<<"sum: "<<accumulate(coll.begin(),coll.end(),0)<<endl; //[beg,end) inital value 计算所有元素总和
//-100+1+2+3+...+9
cout<<"sum: "<<accumulate(coll.begin(),coll.end(),-100)<<endl; //[beg,end) inital value 计算所有元素总和
//1*1*2*3*...*9
cout<<"product: "<<accumulate(coll.begin(),coll.end(),1,multiplies<int>())<<endl; //[beg,end) inital value op(相乘)
//0*1*2*3*...*9
cout<<"product: "<<accumulate(coll.begin(),coll.end(),0,multiplies<int>())<<endl; //[beg,end) inital value op(相乘)
system("pause");
return 0;
}
inner_product(beg1,end1,beg2,initValue)
inner_product(beg1,end1,beg2,initValue,op1,op2)
以上第一种形式计算并返回[beg,end)区间和"以beg2为起始的区间"的对应元素组(再加上initValue)的内积:
initValue=initValue+elem1*elem2
以上第二种形式将[beg,end)区间和"以beg2为起始的区间"内的对应元素组进行op2运算,然后再和initValue进行op1运算,并将结果返回:
initValue=op1(initValue,op2(elem1,elem2))
如果第一区间为空(beg1==end1),则两者都返回initValue。
调用者必须确保"以beg2为起始的区间"内含有足够元素空间。
代码示例:
#include"fuzhu.h"
using namespace std;
int main()
{
list<int> coll;
INSERT_ELEMENTS(coll,1,6);
PRINT_ELEMENTS(coll);
//0+(1*1)+(2*2)+...+(6*6)
cout<<"inner product: "<<inner_product(coll.begin(),coll.end(), //first range
coll.begin(),0)<<endl; //second range initial value
//0+(1*6)+(2*5)+...+(6*1)
cout<<"inner reverse product: "<<inner_product(coll.begin(),coll.end(),
coll.rbegin(),0)<<endl;
//1*(1+1)*(2+2)*(3+3)*...*(6+6)
cout<<"product of sums: "<<inner_product(coll.begin(),coll.end(), //first range
coll.begin(),1,multiplies<int>(),plus<int>())<<endl; //second range initial value 元素之间用*,第一第二区间元素之间用+
system("pause");
return 0;
}
将相对值转换为绝对值
partial_sum(sourceBeg,sourceEnd,destBeg)
partial_sum(sourceBeg,sourceEnd,destBeg,op)
第一形式计算源区间(sourceBeg,sourceEnd)中每个元素的部分和,然后将结果写入destBeg为起点的目标区间.
a1,a1+a2,a1+a2+a3,...
第二形式将源区间(sourceBeg,sourceEnd)中每个元素和其先前所有元素进行op运算,并将结果写入以destBeg为起点的目标区间.
a1,a1 op a2,a1 op a2 op a3,...
第一形式相当于把一个相对值序列转换为一个绝对值序列。就此而言,partial_sum正好和adjcent_sum()互补。
源区间和目标区间可以相同。
调用者必须确保目标区间足够大,要不就得使用插入型迭代器。
代码示例:
#include"fuzhu.h"
using namespace std;
int main()
{
vector<int> coll;
INSERT_ELEMENTS(coll,1,6);
PRINT_ELEMENTS(coll);
//a1,a1+a2,a1+a2+a3,...
partial_sum(coll.begin(),coll.end(),ostream_iterator<int>(cout," "));
cout<<endl;
//a1,a1*a2,a1*a2*a3,...
partial_sum(coll.begin(),coll.end(),ostream_iterator<int>(cout," "),multiplies<int>());
cout<<endl;
system("pause");
return 0;
}
将绝对值转换为相对值与以上过程相反:
#include"fuzhu.h"
using namespace std;
int main()
{
deque<int> coll;
INSERT_ELEMENTS(coll,1,6);
PRINT_ELEMENTS(coll);
//a1,a2-a1,a3-a2,...
adjacent_difference(coll.begin(),coll.end(),ostream_iterator<int>(cout," "));
cout<<endl;
//a1,a1+a2,a2+a3,...
adjacent_difference(coll.begin(),coll.end(),ostream_iterator<int>(cout," "),plus<int>());
cout<<endl;
//a1,a1*a2,a2*a3,...
adjacent_difference(coll.begin(),coll.end(),ostream_iterator<int>(cout," "),multiplies<int>());
cout<<endl;
system("pause");
return 0;
}
综合示例(绝对值相对值相互转换):
#include"fuzhu.h"
using namespace std;
int main()
{
vector<int> coll;
coll.push_back(17);
coll.push_back(-3);
coll.push_back(22);
coll.push_back(13);
coll.push_back(13);
coll.push_back(-9);
//原coll
PRINT_ELEMENTS(coll,"coll: ");
//a1,a2-a1,a3-a2,...
adjacent_difference(coll.begin(),coll.end(),coll.begin());
PRINT_ELEMENTS(coll,"relative: ");
//a1,a1+a2,a1+a2+a3,...
partial_sum(coll.begin(),coll.end(),coll.begin());
PRINT_ELEMENTS(coll,"absolute: ");
system("pause");
return 0;
}