【问题标题】:what is the difference between these three algorithm on the basis of time Complexity?这三种基于时间复杂度的算法有什么区别?
【发布时间】:2020-03-15 13:29:59
【问题描述】:

所有这三种算法只是计算大小为 10 的数组的总和。在这里,我对时间复杂度和我想要哪个更快。你能帮我理解一下时间复杂度吗?

算法 1
在算法 1 中,循环运行了 10 次。

int arr[10] = {1, 2, 3, 4, 5 ,6 ,7, 8, 9, 10};
int sum = 0;
int size = 10;
int i = 0;
for(int i = 0; i < size; i++){
    sum += arr[i];
}
cout<<sum;

算法 2
在算法 2 中,循环运行的是数组大小的一半,但在每次迭代中它执行双倍操作。减少迭代次数会让算法更快吗?

int arr[10] = {1, 2, 3, 4, 5 ,6 ,7, 8, 9, 10};
int sum = 0;
int size = 10;
int i = 0;
for(int i = 0; i < size/2; i++){
    sum += arr[i];
    sum += arr[size-1-i];
}
cout<<sum;

算法 3

int arr[10] = {1, 2, 3, 4, 5 ,6 ,7, 8, 9, 10};
int sum = 0;
int size = 10;
int i = 0;

for(i = 0; i < size/2; i++){
    sum += arr[i];
}

for(int j = i; j < size; j++){
    sum += arr[j];
}
cout<<sum;

【问题讨论】:

  • 请注意,时间复杂度与实时性没有直接关系。尽管它们都具有相同的复杂性,但它们可能具有不同的现实世界性能。这两件事不应该混为一谈。所以问“哪个更快”是相当困难的,如果不是不可能回答的话,并且与大哦无关

标签: c++ algorithm big-o


【解决方案1】:

简答:它们都具有相同的时间复杂度,O(n)。

就时间复杂度(大哦符号)而言,它们都是相同的。

第一个执行(one operation * size of array),即O(n) 复杂度(考虑到n 是数组的大小)。
第二个执行(2 operations * (size of array) / 2),即O(2 * n / 2),也就是O(n)。
第三个执行(1 operation * size of array / 2 + 1 operation * size of array / 2),也就是O(n)。

这 3 种算法在实时执行上可能略有不同,但这与缓存优化和相关主题有关。

【讨论】:

  • 我想知道我是否必须更快地运行我的代码,然后我需要减少操作次数或迭代次数。那正确吗?另外,哪个稍微快一点?也
  • 要使代码更快,您需要减少操作数。
  • 考虑到缓存优化,first算法稍微快一些。因为没有额外的算术加法(如第二个),并且循环只运行一次,所以如果 cpu 必须做出一些预测,它会在第三个算法中至少两次命中错误预测,因为它退出了循环并进入一个新的循环。
【解决方案2】:

这里似乎所有三个代码的大约时间是不同的,因为循环运行的次数 n 和 n/2 不同。但是当我们进入它的分钟细节时,可以看到执行的语句数量是相同的。 .

首先

1 in loop;
loop runs n times;
total=n;

秒

2 in loop; 
loop runs n/2 times;
total n

第三

   1 in first loop;
   loop runs n/2 times;
   total for first is n/2;
   similarly in second ;
   total n

由于执行次数相同,因此大约时间相同

【讨论】:

    【解决方案3】:

    如前所述,所有算法都有O(n) 复杂度。但执行时间可能会有所不同。

    有一个方便的服务Quick C++ Bechmark。我使用下一个代码测试了 4 种算法

    #include <array>
    #include <numeric>
    constexpr int SIZE = 10000;
    std::array<int, SIZE> arr;
    
    static void algo1(benchmark::State& state) {
      std::iota(begin(arr), end(arr), 0);
      for (auto _ : state) {
        int sum = 0;
        for(int i = 0; i < SIZE; i++){
            sum += arr[i];
        }
        benchmark::DoNotOptimize(sum);
      }
    
    }
    BENCHMARK(algo1);
    static void algo2(benchmark::State& state) {
      std::iota(begin(arr), end(arr), 0);
      for (auto _ : state) {
        int sum = 0;
        for(int i = 0; i < SIZE/2; i++){
            sum += arr[i];
            sum += arr[SIZE-1-i];
        }
        benchmark::DoNotOptimize(sum);
      }
    }
    BENCHMARK(algo2);
    static void algo3(benchmark::State& state) {
      std::iota(begin(arr), end(arr), 0);
      for (auto _ : state) {
        int sum = 0, i;
        for(i = 0; i < SIZE/2; i++){ sum += arr[i]; }
        for(int j = i; j < SIZE; j++){ sum += arr[j]; }
        benchmark::DoNotOptimize(sum);
      }
    }
    BENCHMARK(algo3);
    static void algo4(benchmark::State& state) {
      std::iota(begin(arr), end(arr), 0);
      int sum;
      for (auto _ : state) {
        sum = std::accumulate(begin(arr), end(arr), 0);
        benchmark::DoNotOptimize(sum);
      }  
    }
    BENCHMARK(algo4);
    
    The results are:
    algo1: 2770
    algo2: 2913
    algo3: 2782
    algo4: 2770
    

    总结:algo2有点慢,algo1、algo3、algo4执行时间相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-29
      • 1970-01-01
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      • 2020-12-02
      • 1970-01-01
      相关资源
      最近更新 更多