【问题标题】:Algorithm time complexity for various nested for loops各种嵌套for循环的算法时间复杂度
【发布时间】:2013-11-05 14:20:07
【问题描述】:

我对这个 SO 帖子有疑问:Understanding How Many Times Nested Loops Will Run

其中 3 个嵌套 for 循环的通用公式是:n(n+1)(n+2)/3。我真的不知道为什么第二个内循环运行 n+1 次而外循环运行 n 次(内循环在退出 for 循环之前不会再运行一次吗?无论哪种方式......一般公式是

n(n+1)(n+2)...(n+r-1)
---------------------
         r!

这里,r 是嵌套循环的数量。

我想知道这个公式对于嵌套循环是否总是相同的,或者它是否根据 for 循环内的比较而改变...如果它是基于比较,那么如果在考试中,我如何确定公式我得到了一些不同的for循环?如果 for 循环的比较与创建该公式的 SO 帖子中的比较不同,我该如何生成或提出这个公式?

【问题讨论】:

  • 只是算术级数的总和。您可以使用任何您想要的方法计算迭代总数。
  • @Mikhail 我不太明白如何推导出公式。
  • 对于未知代码的复杂度没有通用的公式。 “3 个嵌套循环”对算法的定义不够好,无法做出任何估计。
  • @AlexeiLevenkov 在内部循环的局部计数器变量是外部循环的局部计数器变量的函数的情况下,我如何推导出公式?所以说一个 for 循环是 (i=0; i

标签: c# algorithm


【解决方案1】:

您必须训练自己的思维识别并遵循执行模式,并针对特定情况提出一个公式。一般的经验法则是,如果一个for 循环将运行其中的代码x 次,并且它内部有一个循环将运行y 次,那么内部循环内的代码将运行x*y次。

最常见的for 循环类型从零开始并以 1 递增,直到达到某个数字,如下所示:

for(int i = 0; i < x; i++)
    for(int j = 0; j < y; j++)
        for(int k = 0; k < z; k++)
            // code here runs x * y * z times

为了回答您的问题,如果您更改任何for 循环的任何部分,它将更改内部代码的执行次数。您需要通过考虑逻辑代码执行来确定执行次数。

for(int i = 1; i < x; i++)
    for(int j = 0; j < y * 2; j++)
        for(int k = 0; k < z; k += 2)
            // code here runs (x - 1) * (y * 2) * (z / 2) times

在上面的示例中,每个for 循环都以不同的方式进行了调整。请注意,运行次数的总体公式几乎保持不变,但现在每个循环每次被命中时运行的次数都不同。

当循环的变量影响多个循环时,事情会变得更加复杂。

for(int i = 0; i < x; i++)
    for(int j = i; j < y; j++) // notice how `j` starts as `i`
        // Code here runs `y` times the first time through the outer loop,
        // then `y - 1` times,
        // then `y - 2` times,
        // ...
        // if x < y, the pattern continues until the xth time,
        // when this loop runs `y - x` times.
        // if x > y, the pattern will stop when y == x, and
        // code here will run 0 times for the remainder of
        // the loops.

所以在最后一个示例中,假设x &lt; y,循环将运行y + (y-1) + (y-2) ... + (y-x) 次。

【讨论】:

  • +1 以获得出色的解释。也许你应该提到如果循环变量依赖于问题(例如排序算法),它会更加复杂。在这种情况下,您可以计算最佳、最差和平均复杂度。
  • 感谢您的精彩解释。
【解决方案2】:

它会根据内在价值而变化。 例子。

        for (int i = 0; i < 100; i++)
        {
            //this loop will run 100 times.
            for (int i1 = 0; i1 < 100; i++)
            {
                // This will run 100 times every outer loop int.
                // This means that for each index i in the outer loop this will run 100 times. 
                // The outer loop runs 100 time and this runs 10,000 times in total.
            }
        }



        for (int i = 0; i < 100; i++)
        {
            //this loop will run 100 times.
            for (int i1 = 0; i1 < 10; i++)
            {
                // This will run 10 times every outer loop int.
                // This means that for each index i in the outer loop this will run 10 times. 
                // The outer loop runs 100 time and this runs 1,000 times in total.
            }
        }

查看它的一种更简单的方法可能是这样。

        for (int i = 0; i < 10; i++)
        {
            //this loop will run 10 times.
            Console.WriteLine("int i = " + i.ToString()");
            for (int i1 = 0; i1 < 10; i++)
            {
                // This will run 10 times every outer loop int.
                // This means that for each index i in the outer loop this will run 10 times. 
                // The outer loop runs 10 time and this runs 100 times.
                Console.WriteLine("int i2 = " + i2.ToString()");
            }
        }

这会输出这个。

        int i = 0
        int i2 = 0
        int i2 = 1
        int i2 = 2
        int i2 = 3
        int i2 = 4
        int i2 = 5
        int i2 = 6
        int i2 = 7
        int i2 = 8
        int i2 = 9
        int i = 1
        int i2 = 0
        int i2 = 1
        int i2 = 2
        int i2 = 3
        int i2 = 4
        int i2 = 5
        int i2 = 6
        int i2 = 7
        int i2 = 8
        int i2 = 9

等等。

公式基于内部循环数。 (循环结束时打开。)

【讨论】:

  • 我的教授将内部循环的局部变量分配为外部 for 循环局部变量的函数。因此,他可以说 i1=i,而不是说 i1=0。所以现在你可以想象,判断内循环运行的频率会稍微困难一些,因为它是外循环的函数。在那种情况下我会怎么做?我只是通过写下代码运行时计数器的样子来蛮力还是可以使用一些公式。
  • 您可以使用整数计数器并在每个循环中增加一个整数。公式更好,因为它需要处理的数据更少。基本上,如果起始 int 相同,您可以将这些数字全部相乘。例如,如果您将 i1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多