问题描述
int coffee(int n) {
int s = n * n;
for (int q = 0; q < n; q++)
s = s - q;
for (int q = n; q > 0; q--)
s = s - q;
return s + 2;
}
int mocha(int n) {
int r = 0;
for (int i=0; i<=n; i = i+16)
for (int j=0; j<i; j++)
r++;
return r;
}
int fun(int n) {
int j=0;
for (int k = 16; coffee(k) * mocha(k) - k <= n; k+=16) {
j++;
cout << "I am having so much fun with asymptotics!" << endl;
}
return j;
}
-
如何计算“ fun”函数的最坏情况渐近运行时间? 我确定咖啡的运行时间为$ \ Theta(n)$,而摩卡咖啡的运行时间为$ \ Theta(n ^ 2)$ 但是我从那里去哪里?
解决方法
在我们分析运行时间复杂度的算法之前,在渐近分析的上下文中需要注意的一点(参考:1,2)是O(f(n))表示最坏的情况(上限)而不是Θ(f(n))。
您已经正确提到了O(n)
的最坏情况渐近运行时间coffee
和O(n2)
的{{1}},其中mocha
是相应输入的大小功能。
现在,查看您的多功能算法,很明显,功能n
是输入fun
的入口点。 n
(使用fun
遍历n
,因此此代码块的运行时复杂度最差的情况为k
。
O(n)
对于for (int k = 16; /* coffee(k) * mocha(k) */ - k <= n; k+=16) {
j++;
cout << "I am having so much fun with asymptotics!" << endl;
}
的每个值,将调用k
和coffee
,因此它们将被调用mocha
次,总共被调用n/16
。因此,下面是正确计算函数O(n)
的最坏情况渐近运行时间的逻辑:
fun
O(fun) = O( O(n/16) * ( O(coffee) + O(mocha) ) )
= O( O(n/16) * ( O(n) + O(n^2) ) )
= O( O(n^2 / 16) + O(n^3 / 16) )
≃ O(n^3)
可以简化为O( O(n2/16) + O(n3/16) )
,因为O(n3)
是公式n3
中的关键因素。