【问题标题】:What is Big O of a loop?什么是循环的大 O?
【发布时间】:2011-08-06 15:15:43
【问题描述】:

我正在阅读Big O notation。它表示,

循环的大 O 是循​​环的迭代次数 循环中的语句数。

这是一个代码sn-p,

for (int i=0 ;i<n; i++)
{
    cout <<"Hello World"<<endl;
    cout <<"Hello SO";
}

现在根据定义,大O应该是O(n*2),但它是O(n)。谁能帮助我解释为什么会这样? 提前致谢。

【问题讨论】:

  • 循环内只有n次迭代
  • 但是循环中有2条语句
  • @JustAnotherProgrammer 看到我的回答,循环中的语句需要常数时间,两个常数使另一个常数。重要的是循环中的迭代次数。
  • 不不,它的大 O 将是 O(n),因为我们使用时间方程循环运行 n+1 次,所以大 O 将是 n 而不是 n2..

标签: big-o


【解决方案1】:

如果您检查 O() 表示法的定义,您会发现(乘数)常量无关紧要。

要在循环中完成的工作是不是 2. 有两个语句,对于每个语句,您必须执行几个机器指令,可能是 50 或 78,或其他,但这与渐近复杂度计算完全无关,因为它们都是常数。它不依赖于n。这只是 O(1)。

O(1) = O(2) = O(c) where c is a constant.
O(n) = O(3n) = O(cn)

【讨论】:

  • 复杂性是根据指令来衡量的(也许不是正确的短语,但我不知道更好的短语)。如果他想测量 std::cout 的复杂性,他是对的。如果他想考虑所有低级功能,那么您是对的。尽管正如您所指出的那样,常数并不重要。
【解决方案2】:

O(n) 用于将循环与数学函数混淆(如 n^2、n^m、..)。

所以如果你有这样的循环

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

循环采用的最佳描述数学函数是用 O(n) 计算的(其中 n 是介于 0..infinity 之间的数字)

如果你有这样的循环

     for(int i =0 ; i< n*2; i++) {

     }

意味着它将花费 O(n*2);数学函数 = n*2

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

         }
    }

这个循环需要 O(n^2) 时间;数学函数 = n^n 这样你就可以计算出你的循环需要多长时间 n 10 或 100 或 1000

通过这种方式,您可以为循环等构建图表。

【讨论】:

  • 如果内部循环 for(int j = 0; j &lt;= n; j++) { 小于或等于 ,Big(n^2) 会发生变化。
【解决方案3】:

Big-O 表示法在设计(和定义)上忽略了常数乘数,因此 O(n) 和 O(2n) 完全相同。我们通常写成 O(n),因为它更短更熟悉,但 O(2n) 的意思是一样的。

【讨论】:

    【解决方案4】:

    首先,不要称它为“大 O”。这是错误和误导的。您真正想要找到的是渐近将执行多少条指令作为 n 的函数。考虑 O(n) 的正确方法不是作为一个函数,而是作为一组函数。更具体地说:

    O(n) 是所有函数 f(x) 的 集合,因此存在一些常数 M 和一些数字 x_0,其中对于所有 x > x_0,f(x)

    换句话说,当 n 变得非常大时,函数的增长(例如,指令的数量)将在某个点上以具有某个常数系数的线性函数为界。

    根据您对指令的计数方式,循环可以执行不同数量的指令,但无论如何它最多只能迭代 n 次。因此指令的数量在 O(n) 中。它是否重复 6n 或 .5n 或 100000000n 次,或者即使它只执行恒定数量的指令都没有关系!它仍然属于 O(n) 中的函数类。

    再扩展一点,类 O(n*2) = O(0.1*n) = O(n),而类 O(n) 严格包含在类 O(n^2) 中。结果,该循环也在 O(2*n) 中(因为 O(2*n) = O(n)),并且包含在 O(n^2) 中(但上限并不严格)。

    【讨论】:

      【解决方案5】:

      O(n) 表示循环时间复杂度随元素数量线性增加。

      2*n 仍然是线性的,所以你说循环的顺序是 O(n)。

      但是,您发布的循环是 O(n),因为循环中的指令需要恒定的时间。常数的两倍仍然是常数。

      【讨论】:

        【解决方案6】:

        程序中增长最快的项是循环,其余的只是常数,所以我们选择增长最快的项,即循环 O(n)

        如果您的程序中有嵌套循环,则此 O(n) 将被忽略,并且您的算法将得到 O(n^2),因为您的嵌套循环具有增长最快的术语。

        【讨论】:

          【解决方案7】:

          通常big O 表示函数中的主要操作数。

          在本教程中,我们过度使用了 n 个元素。所以复杂度是 O(n)

          肯定不是 O(n^2),因为二次是这些算法的复杂性,例如冒泡排序,它将输入中的每个元素与所有其他元素进行比较。

          您还记得,冒泡排序,为了确定插入元素的正确位置,将每个元素与列表中的其他 n 进行比较(冒泡行为)。

          您最多可以声称您的算法具有复杂性 O(2n),因为它为输入中的每个元素打印 2 个短语,但在 big O 表示法中 O(n)是 O(2n)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-01-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-03-08
            • 2011-05-04
            相关资源
            最近更新 更多