基于此代码:
int poow(int x,int y)
{
if(y==0)
return 1;
if(y%2!= 0)
return poow(x,y-1)*x;
return poow(x,y/2)*poow(x,y/2); //this line
}
我试图看到复杂性:我们假设我们有n = 2 ^ k
我们有T(0)= 1
T(N)= 2 * T(N / 2)+ C
T(n)= 2 ^ i * T(n / 2 ^ i)+ i * c
对于i = k,我们得到T(n)= 2 ^ k * T(n / 2 ^ k)+ k * c
T(n)= 2 ^ k * T(1)+ k * c
T(n)= 2 ^ k * c2 + k * c
我被困在这里?如何继续计算复杂性以及更改此行时的区别:
return poow(x,y/2)*poow(x,y/2); //this line
带
int p=poow(x,y/2);
return p*p;
就复杂性而言!
答案 0 :(得分:1)
从适当的重复开始。复杂性完全基于y
,因此我们可以将重现写为
T(0) = 1
T(y) = y is even: 2 * T(y / 2)
y is odd: T(y - 1) + 1
最糟糕的情况是每个除以2会给我们留下一个奇数,这会导致复杂性
T(2^n-1) = 1 + 2 * (1 + 2 * (1 + 2 * ( ... * T(1)))) =
= 2 ^ 0 + 2 ^ 1 + 2 ^ 2 + 2 ^ 3 + ... + 2 ^ (n - 1) + 2 ^ (n - 1) =
= 2 ^ n - 1 + 2 ^(n - 1) = 3 * 2 ^ (n - 1) - 1
T(y) = O(y)
最好的情况是2的力量:
T(2^n) = 2 * 2 * ... * 2 * T(1) = 2 ^ n * (1 + 1) = 2 ^ (n + 1) = 2 * 2 ^ n
T(y) = O(y)
现在我们如何优化整个功能呢?
T'(0) = 1
T'(y) = y is even: T(y / 2) + 1
y is odd: T(y - 1) + 1
最坏情况:
T'(2^n - 1) = T(2^n - 2) + 1 = T(2^(n - 1) - 1) + 1 + 1 = ... =
= T(1) + 1 + 1 + 1 + ... =
= 2 + 1 + 1 + 1 + ... =
= 1 + ln(2^n) / ln(2) * 2 =
= 1 + 2 * n
T'(y) = O(log y)
最佳案例:
T'(2 ^ n) = T(1) + 1 + 1 + ... =
= 2 + 1 + 1 + ... =
= 2 + ln(2^n) / ln(2)
= n + 2
T'(y) = O(log y)
因此,优化版本肯定更快(线性与对数复杂度)。
答案 1 :(得分:0)
有时代码分析侧重于理论,而不是实际。
代码有一个错误。
if(y%2!= 0)
return poow(x,y-1)*x;
// should be
if(y%2!= 0)
return poow(x,y-y%2)*x;
// better alternative, use
unsigned poow(unsigned x, unsigned y)
如果没有修复,调用poow(1,-1)
会导致无限递归并且可能会发生堆栈溢出。所以在最后一行中的O(∞)是return poow(x,y/2)*poow(x,y/2);
或int p=poow(x,y/2);
return p*p;
。