• LeetCode 303.区域检索-数组不可变(accumulate()和for循环差异分析)


    给定一个整数数组  nums,求出数组从索引 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点。

    示例:

    给定 nums = [-2, 0, 3, -5, 2, -1],求和函数为 sumRange()
    
    sumRange(0, 2) -> 1
    sumRange(2, 5) -> -1
    sumRange(0, 5) -> -3

    说明:

    1. 你可以假设数组不可变。
    2. 会多次调用 sumRange 方法。
    #include <vector>
    #include <iostream>
    #include <numeric>
    
    using namespace std;
    
    static int x = []() {std::ios::sync_with_stdio(false); cin.tie(0); return 0; }();
    class NumArray {
    public:
        NumArray(vector<int> nums) {
            sumnums = nums;
        }
        
        int sumRange(int i, int j) {
            return accumulate(sumnums.begin()+i, sumnums.begin()+j+1, 0);
        }
    private:
        vector<int> sumnums;
    };
    
    int main()
    {
        vector<int> vec = {-2, 0, 3, -5, 2, -1};
        NumArray *A = new NumArray(vec);
        cout << A->sumRange(0, 2);
        
        return 0;
    }
    #include <vector>
    #include <iostream>
    #include <numeric>
    
    using namespace std;
    
    static int x = []() {std::ios::sync_with_stdio(false); cin.tie(0); return 0; }();
    class NumArray {
    public:
        NumArray(vector<int> nums) {
            for(int i = 1; i < nums.size(); ++i){
                nums[i] += nums[i-1];
            }
            sumnums = nums;
        }
        
        int sumRange(int i, int j) {
            if(i == 0)
                return sumnums[j];
            return sumnums[j] - sumnums[i-1];
        }
    private:
        vector<int> sumnums;
    };
    
    int main()
    {
        vector<int> vec = {-2, 0, 3, -5, 2, -1};
        NumArray *A = new NumArray(vec);
        cout << A->sumRange(0, 2);
        
        return 0;
    }

    上面是accumulate()下面是for循环

    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;
    }

    时间复杂度同是O(n),耗时差这么多。

    举个栗子

    #include <iostream>
    #include <vector>
    #include <numeric>
    
    using namespace std;
    
    vector<int> vec = { 1, 2, -5, 6 };
    int sum;
    
    void func1()
    {
        for (int i = 0; i < vec.size(); ++i) {
            sum += vec[i];
        }
    }
    
    void func2()
    {
        accumulate(vec.begin(), vec.end(), 0);
    }
    
    int main()
    {
    
        return 0;
    }

    直接查看汇编代码

    首先我怀疑编译器在进行begin()操作或者使用容器时,耗费了时间。

    void func1()
    {
        for (int i = 0; i < vec.size(); ++i) {
            sum += *(vec.begin()+i);
        }
    }

    同时将LeetCode上for循环数组形式改为begin()形式。

    得到汇编代码和运行结果

    并没有影响,那么唯一的可能性是,在调用accumulate()时使用了其他内联函数,或者编译器进行了数据资源的申请。

  • 相关阅读:
    Swift使用闭包表达式
    css + html 小知识总结
    关于javascript的误区
    什么是cookie
    css技术和实例
    闭包练习
    web 小知识
    javascript------>(此文转发)
    Spring Boot 系列 @ControllerAdvice 拦截异常并统一处理
    JSR-303 数据校验学习
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/10577733.html
Copyright © 2020-2023  润新知