zoukankan      html  css  js  c++  java
  • 数值算法(accumluate,inner_product,partial_sum,adjacent_difference,power,itoa)

    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;
    }
    1. 一定要提供一个init这样明确的初始值,这样因为在[first.last)中为空时,仍然有明确的定义
    2. 双参操作符不一定具有交换性和结合性,因为所有的accumulate操作都有明确的定义,先初始化init操作,然后对[first,last)中的每一个iterator i,从头到尾执行result=result+*i,或result=binary_op(result,*i),也就是先用init和[first,last)中的*first做运算,在用得到的结果和[first,last)中剩余的每个元素做运算
    3. 二元仿函数不必满足交换律和结合律
    #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;
    }
    1. 计算[first1,last1)和[first2,last2+(last1-first1))的一般化内积,如果要计算两个vector的一般化内积,把init置为0
    2. 第一个版本先执行result=init,然后执行result=result+(*i)*(first2+(i-first1))
    3. 第二个版本先执行result=init,再执行binary_op2(*i,*(first2+(i-first1)),然后执行binary_op1(result,binary_op2(*i,*(first2+(i-first1))),依次循环...
    4. 二元仿函数不必满足交换律和结合律
    #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

    1. 如果result==first,可以就地计算元素的差,储存第一元素的值可以重建输入区间的内容
    2. 先将*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++;
        }
    }

      

  • 相关阅读:
    《算法导论》读书笔记之第16章 贪心算法—活动选择问题
    C语言综合实验1—学生信息管理系统
    《算法导论》读书笔记之第15章 动态规划[总结]
    《算法导论》读书笔记之第11章 散列表
    模板类中定义list<T>::iterator iter在g++下不识别的解决办法
    C语言参考程序—无符号一位整数的四则运算
    《算法导论》读书笔记之第15章 动态规划—最优二叉查找树
    C语言综合实验2—长整数运算
    递归与尾递归总结
    《算法导论》读书笔记之第13章 红黑树
  • 原文地址:https://www.cnblogs.com/tianzeng/p/10388958.html
Copyright © 2011-2022 走看看