accumulate
template <class InputIterator,class T> T accumulate(InputIterator first, InputIterator last, T init) { for (; first != last; first++) { init = init + *first; } return init; } 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; }
- 一定要提供一个init这样明确的初始值,这样因为在[first.last)中为空时,仍然有明确的定义
- 双参操作符不一定具有交换性和结合性,因为所有的accumulate操作都有明确的定义,先初始化init操作,然后对[first,last)中的每一个iterator i,从头到尾执行result=result+*i,或result=binary_op(result,*i),也就是先用init和[first,last)中的*first做运算,在用得到的结果和[first,last)中剩余的每个元素做运算
- 二元仿函数不必满足交换律和结合律
#include <iostream> #include <numeric> #include <vector> #include <functional> using namespace std; class F { public: int operator()(int i,int j) { return i-j; } }; int main() { vector<int> v{1,2,3}; int t=accumulate(v.begin(),v.end(),1,multiplies<int>()); cout<<"t:"<<t<<endl; int t1=accumulate(v.begin(),v.end(),0,F()); cout<<"t1:"<<t1<<endl; return 0; }
inner_product
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 BinaryOperation1, class BinaryOperation2, class T> 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; }
- 计算[first1,last1)和[first2,last2+(last1-first1))的一般化内积,如果要计算两个vector的一般化内积,把init置为0
- 第一个版本先执行result=init,然后执行result=result+(*i)*(first2+(i-first1))
- 第二个版本先执行result=init,再执行binary_op2(*i,*(first2+(i-first1)),然后执行binary_op1(result,binary_op2(*i,*(first2+(i-first1))),依次循环...
- 二元仿函数不必满足交换律和结合律
#include <iostream> #include <numeric> #include <vector> #include <functional> using namespace std; class F1 { public: int operator()(int i,int j) { //clog<<" 执行F1"<<endl; return i+j; } }; class F2 { public: int operator()(int i,int j) { //clog<<" 执行F2"<<endl; return i/j; } }; int main() { vector<int> v{1,2,3}; vector<int> v1{1,2,3,4,5,6}; int t=inner_product(v.begin(),v.end(),v1.begin(),0); cout<<"t:"<<t<<endl; int t1=inner_product(v.begin(),v.end(),v1.begin(),0,F1(),F2()); cout<<"t1:"<<t1<<endl; return 0; }
parital_sum
计算部分总和,先将*first赋值result,再将*first和*(first+1)赋值给*(result+1)等等,result可以等于first,次函数与adjacent_difference,返回值指向输出算法的尾区间:result+(last-first)
template <class InputIterator, class OutputIterator> OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result) { if (first == last) { return result; // 区间内容为空直接返回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 BinaryOperation> OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op) { if (first == last) { return result; // 区间内容为空直接返回result } *result = *first; // 首先记录第一个元素(即原容器中第一个元素内容不变) iterator_traits<InputIterator>::value_type value = *first; while (++first != last) { value = binary_op(value, *first); *++result = value; } return ++result; }
adjacent_difference
- 如果result==first,可以就地计算元素的差,储存第一元素的值可以重建输入区间的内容
- 先将*first赋值给*result,对于[first+1,last)中的每个iterator i,第一版本(重载operator -)将*i与*(i-1)之差赋值给*(result+(i-first)),第二版本(自己重定义函数对象)是binary(*i,*(i-1))赋值给*(result+(i-first))
template <class InputIterator, class OutputIterator> OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result) { if (first == last) { return result; // 区间内容为空直接返回result } *result = *first; // 首先记录第一个元素(即原容器中第一个元素内容不变) //return __adjacent_difference(firsts,last,result,value_tyope(first)); iterator_traits<InputIterator>::value_type value = *first; while (++first != last) // 之后的元素为本位置-前一个位置的值 {//__adjacent_difference的内容 T tmp = *first; *++first = 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 } *result = *first; // 首先记录第一个元素(即原容器中第一个元素内容不变) iterator_traits<InputIterator>::value_type value = *first; while (++first != last) { T tmp = *first; *++first = binary_op(tmp, value); value = tmp; } return ++result; }
power
template <class T, class Integer> inline T power(T x, Integer n) { return power(x,n,multiplies<T>()); // multiplies<T>()是一个仿函数的临时对象,意为相乘 } // 版本2,如果指定为乘方运算,则当n >= 0时返回x^n // MonoidOperation必须满足结合律,可不满足交换律 template <class T, class Integer, class MonoidOperation op> T power(T x, Integer n, MonoidOperation op) { if (n == 0) // 直接返回1也行 { return identity_element(op); // 取出证同元素 } else // 过滤低位的0 { while ((n & 1) == 0) { n >>= 1; // n右移一位 x = op(x, x); // x = x op 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; }
itoa
template <class ForwardIterator, class T> void iota(ForwardIterator first, ForwardIterator last, T value) { while (first != last) { *first = value++; } }