我的计算机科学II决赛是明天,我需要一些帮助,了解如何找到代码段的Big-Oh。我在互联网上搜索过,但未能找到任何我需要了解它的例子。
这是我们的样本决赛中的一个问题:
for(int pass = 1; i <= n; pass++)
{
for(int index = 0; index < n; index++)
for(int count = 1; count < n; count++)
{
//O(1) things here.
}
}
}
我们应该找到算法的顺序(Big-Oh)。
我认为它将是O(n ^ 3),这就是我得出的结论
for(int pass = 1; i <= n; pass++) // Evaluates n times
{
for(int index = 0; index < n; index++) // Evaluates n * (n+1) times
for(int count = 1; count < n; count++) // Evaluates n * n * (n) times
{
//O(1) things here.
}
}
}
// T(n) = (n) + (n^2 + n) + n^3
// T(n) = n^3 + n^2 + 2n
// T(n) <= c*f(x)
// n^3 + n^2 + 2n <= c * (n^3)
// O(n) = n^3
我只是不确定我是否正确地做到了。有人可以解释如何评估这样的代码和/或确认我的答案吗?
答案 0 :(得分:2)
是的,它是O(n^3)
。但是:
for(int pass = 1; pass <= n; pass++) // Evaluates n times
{ //^^i should be pass
for(int index = 0; index < n; index++) //Evaluates n times
for(int count = 1; count < n; count++) // Evaluates n-1 times
{
//O(1) things here.
}
}
}
由于你有三层嵌套for循环,嵌套循环将被评估n *n * (n-1)
次,最内部for循环内的每个操作都需要O(1)时间,因此总共有{{1}常量操作,按增长顺序为n^3 - n^2
。
如何衡量Big O表示法增长顺序的一个很好的总结可以在这里找到:
从上述文件中引用部分:
嵌套循环
O(n^3)
外循环执行N次。每次外循环执行时,内循环 执行M次。结果,内循环中的语句执行总共N * M. 倍。因此,复杂度为O(N * M)。 在一个常见的特殊情况下,内环的停止条件是
for I in 1 .. N loop for J in 1 .. M loop sequence of statements end loop; end loop;
J <N
的{{1}}(即内循环也执行N次),两个循环的总复杂度为O(N ^ 2)。
类似的理由可以适用于您的情况。
答案 1 :(得分:0)
你是完全正确的。你的例子是O(n ^ 3)。
要找到任何代码段的Big Oh运行时间,你应该考虑这段代码执行O(1)事情的次数。
让我简化你的例子,以便更好地了解这个:
for(int index = 0; index < n; index++) // Evaluates n * (n+1) times
for(int count = 1; count < n; count++) // Evaluates n * n * (n) times
{
//O(1) things here.
}
}
在上述情况下,内循环每次运行外循环运行n次。你的外环也运行了n次。这意味着你要做很多次事情。使它成为O(n ^ 2)。
要注意的另一件事是Big Oh是一个上限。这意味着当你有大量输入时(在你的情况下,n
的值很大时,你应该总是考虑代码会发生什么。这个事实的另一个含义是乘法或加法通过常数对Big Oh界限没有影响。例如:
for(int index = 0; index < n; index++) // Evaluates n * (n+1) times
for(int count = 1; count < 2*n; count++) // Runs 2*n times
{
//O(1) things here.
}
}
此代码的Big Oh运行时间也是O(n ^ 2),因为O(n *(2n))= O(n ^ 2)。