【问题标题】:complexity of code代码复杂度
【发布时间】:2011-01-28 17:37:09
【问题描述】:

只有一个循环的程序的复杂度是多少,是 log n 吗? 有人可以给我一些关于估计代码复杂性的想法吗?

【问题讨论】:

  • 循环次数并不是唯一重要的事情。所以,最好展示代码本身。
  • 另外,复杂性是什么意思?听起来您可能指的是通常的 O() 时间复杂度表示法,但这只是一种复杂度。

标签: java c algorithm


【解决方案1】:

嗯,这真的取决于那个循环中发生了什么。

这个循环是线性时间,即O(n):

int sum = 0;
foreach( int i in SomeCollection )
{
    sum += i;
}

但是,考虑一个在每次迭代期间执行子字符串搜索的循环。现在您必须考虑字符串搜索算法的复杂性。你的问题目前无法回答。如果您想要一个有意义的答案,您将需要提供一个代码示例。

【讨论】:

    【解决方案2】:

    软件复杂性

    有一个研究领域试图准确地量化这一点。

    它叫cyclomatic complexity

    在这种情况下,我相信您的复杂度等级将是 p = 2,因为循环是有条件的,这意味着该方法有两条路径。

    时间复杂度

    如果您指的是time complexity,它仍然只是 O(1),除非循环迭代计数是通过多项式或指数函数得出的,可能间接因为该方法本身在更高的循环中被调用,或者因为循环计数器有效地乘以字符串操作或较低级别的东西。

    【讨论】:

    • +1 不要认为提问者询问的是相对执行时间(即大 O),而是根据不同的执行路径进行测量。
    【解决方案3】:

    要获得一段代码的 Big-O 复杂度,您需要问自己“完成了多少次迭代”?

    当然,问题在于,从代码本身中找出它并不总是那么容易,有时最好看大局并计算完成的操作量。

    例子:

    For (i = 0 ; i < n ; i++ ) {
       //Do stuff
    }
    

    这是 复杂度

    For (i = n ; i > 0 ; i= i/2 ) {
       //Do stuff
    }
    

    这是一个 复杂度...因为在每次迭代中,我都会被减半。

    void Mess (int n) {
        for (i = 0 ; i < n ; i++) {
             //Do stuff
             Mess(n-1);
        } 
    }
    

    现在这看起来像一个简单的循环,因为它用递归调用自己,实际上是一团糟......每次迭代都用 n-1 调用自己 n 次。
    所以在这里从最后开始思考会更容易。如果 n == 1 ,则有 1 次迭代。如果 n == 2 那么它会调用前一个场景两次。
    所以如果我们调用函数,我们可以看到我们会递归得到什么: 最后当然会给我们n!

    底线,它并不总是微不足道的。

    【讨论】:

    • 在您的第二个示例中,循环永远不会结束,因为 i + i/2 将始终为 i + 0(起点)返回 0 :-)
    • 您应该注意,您的分析要求“做事”是一个恒定时间的操作。
    【解决方案4】:

    如果只有一个循环,它可能是循环体执行的次数......当然,在库调用中可能有很多隐藏循环。很容易创建一个循环执行 nO(n^2) 或更糟,如果你有 strlenmemcpy 等发生在循环体内。

    或者更糟糕的是,如果您有一个带有正则表达式的库(或语言),并且它们的正则表达式实现是幼稚的(如 Perl),那么只需一个循环 O(2^n) 就可以很容易地制作一个程序!正确编写的正则表达式实现不会发生这种情况。

    【讨论】:

      【解决方案5】:

      您可以使用“trend-prof”(https://pdfs.semanticscholar.org/8616/7f320e230641299754e0fbd860c44f5895f0.pdf)等工具轻松预测代码的计算时间和复杂度

      Github 中提供了 GuessCompx 库,用于 R 代码的相同目的。

      【讨论】:

        【解决方案6】:

        如果您询问的是 Big-O 时间复杂度,那么 for 循环是循环内任何内容的 n 倍复杂度,其中 n 是循环计数限制。

        所以。如果循环内的代码执行时间是固定的,即如果它的时间复杂度是O(1),那么循环的复杂度就是O(1*n) = O(n)。

        以类似的方式,如果在循环中您有另一个循环将执行m 步骤,那么您的整个代码就是 O(n*m),依此类推。

        【讨论】:

          猜你喜欢
          • 2018-04-05
          • 2017-02-09
          • 2015-02-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-10
          • 2011-10-04
          • 1970-01-01
          相关资源
          最近更新 更多