【问题标题】:Which of the control structure take less time complexity?哪个控制结构的时间复杂度更小?
【发布时间】:2018-06-13 18:47:46
【问题描述】:

在编程中,我们使用了很多控制结构来进行迭代。那么就时间复杂度而言,哪一种是迭代的最佳方式?

int a[500],n=10;
for(int i=0;i<=n;i++)
{
cin>>a[i]
}

如何更改此迭代以降低复杂性?

哪一种是用于迭代的最佳方式:

  1. 同时
  2. 同时做

【问题讨论】:

    标签: c++ algorithm iteration time-complexity


    【解决方案1】:

    这将从i=0 迭代到i=10,因此总共进行了11 次迭代。任何基本循环的时间复杂度都是 O(N)。

    上面提到的所有选项(for-loop、while-loop、do-while-loop)都具有相同的时间复杂度。

    【讨论】:

      【解决方案2】:

      forwhiledo while(还有 goto)实际上是一回事。无论您使用其中一个循环创建什么循环,您始终可以创建一个与所有其他循环具有相同时间复杂度的等效循环。 (几乎是真的。唯一的例外是 do-while 循环必须至少运行一次。)

      例如,你的循环

      for(int i=0;i<=n;i++) {
          ...
      }
      

      对应于

      int i=0;
      while(i<=n) {
          ...
          i++;
      }
      

      int i=0;
      START:
      ...
      i++;
      if(i<=n)
          goto START;
      

      你也可以做一个等效的do-while,但它没有真正意义。

      您应该选择哪一个更多的是设计问题而不是性能问题。一般来说:

      • for - 当你知道循环开始前的迭代次数时
      • while - 当你不知道时
      • do-while - 当你不知道时,但至少一次
      • goto - 从不(存在一些例外情况)

      for 循环的一个好处是您可以声明仅存在于循环范围内的变量,也可以用于循环条件。

      【讨论】:

      • 这个答案是错误的。见stackoverflow.com/questions/20172402/…
      • @user167921 这取决于你如何看待它。如果一个循环运行零次,那么根据定义,它完全等同于没有循环,因此可以用一个空的主体替换。我可以添加一个注释,但你真的认为它有那么重要吗?毕竟,这个问题是关于时间复杂度的。
      • 我现在修好了。
      【解决方案3】:

      与往常一样,您应该为此目的使用缓存技术。因为如果你有兴趣,forwhile 关键字实际上在几乎相同的指令中做同样的事情(两者都用 jmp 指令表示)。同样,银弹不存在。根据您的程序的性质,优化循环的唯一方法是使用缓存或并行化,如果它可以满足您的目标。也许存在只创建一次并多次使用的常量值?如果可能,然后缓存结果。这可以将时间减少到“恒定”。或者以并行方式进行。但我认为这不是正确的方法,编译器会为你做很多事情。更好地专注于您的程序架构

      【讨论】:

        【解决方案4】:

        forwhiledo-whilefor-each 等的使用可以认为是syntactic sugar 的经典示例。它们只是做同样事情的方法,但在某些情况下,某些控制结构可能比其他控制结构“更甜”。例如,如果您想继续迭代,当且仅当布尔值保持 true(例如使用迭代器)时,while 看起来比 for 好得多(这是一个主观评论),但复杂度是一样的。

        while (iter.next()) {
        
        // Do something
        }
        
        for (;iter.next();) {
        // Do something
        }
        

        就时间复杂性而言,它们迭代相同数量的元素,在您的示例中 N=10 因此 O(N)。你怎样才能让它变得更好?这取决于,如果你必须遍历整个数组,大 O 最好的情况总是 O(N)。现在就 ~N 而言,该语句并不总是true。例如,如果您只迭代具有 2 个起点的数组的一半,一个在 i=0,另一个在 i=n-1,您可以获得时间复杂度 ~N/2

        for(int i=0;i<n/2;i++)
        {
           int x = a[i];
           int y = a[n-i-1];
           // Do something with those values
        }
        

        考虑到 ~N/2 -> O(N),大 O 的复杂度相同,但是如果您有一组 10k 条记录,则只需读取 5k 条就是一项成就!在最后一种情况下,我想说的是,如果您想提高代码复杂性,您需要开始检查更好的数据结构和算法(这只是一个简单的愚蠢示例,多种情况下都有漂亮的算法和数据结构)。请记住:forwhile 不是大问题!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多