Performance 理论上是对数复杂度,但实际上是线性复杂度
请查看以下代码以查找X^yPerformance 理论上是对数复杂度,但实际上是线性复杂度,performance,algorithm,theory,big-o,time-complexity,Performance,Algorithm,Theory,Big O,Time Complexity,请查看以下代码以查找X^y /* Find exponent in logarithmic complexity */ int findPower(int base, exponent){ if( 1 == exponent ) return base; return (findPower(base, exponent/2)*findPower(base, exponent-exponent/2)); } int main(int argc, char *argv[]){
/* Find exponent in logarithmic complexity */
int findPower(int base, exponent){
if( 1 == exponent ) return base;
return (findPower(base, exponent/2)*findPower(base, exponent-exponent/2));
}
int main(int argc, char *argv[]){
if(argc < 3) {
printf("Usage :: logpow baseNumber power\n");
return -1;
}
printf("%s ^ %s = %d\n", argv[1], argv[2], findPow( atoi(argv[1]),
atoi(argv[2])) );
return 0;
}
从上面我们可以看到,实际的时间复杂度是线性的,而不是对数的
复杂性如此巨大差异的原因是什么
问候,
微核您的分析不正确,它已打开
当你把N从10亿提高到20亿时,你必须对10亿做两次幂运算。因此,将N加倍将需要完成的功加倍。这是打开的。实际上,您正在从每个调用调用2个函数调用。递归树将是高度为logexponent的二叉树,因此其中的节点数将为2^logexponent==exponent。所以总的来说,它变成了一个线性算法。您可以这样重写它以获得更好的性能:
int findPower(int base, int exponent){
if( 0 == exponent ) return 1;
int temp = findPower(base, exponent/2);
if(exponent % 2 == 0) return temp * temp;
return temp * temp * base;
}
诀窍是,必须存储findPowerbase的值,exponent/2才能获得对数复杂度。递归树仍然有height logexponent,但每个节点现在只有一个子节点,因此将有logexponent节点。如果您实际调用它两次,它将比线性调用更降低性能。如果您已经有了相同的值,则无需再次计算相同的值
正如@David Schwartz所指出的,如果指数增加一倍,代码中的调用数量将增加一倍。但是当您保存这些值时,将指数加倍只需再调用一次。有一个算法复杂性的正式表示: Tn=2Tn/2+c 其中n是指数。给 Tn=θ
分析不正确。是的!从侧面进行的错误分析,如下所述,Tn=2Tn/2+c=>thetan@FlopCoder谢谢:,你的代码运行得非常快:最后一个案例花费了多少时间?0.02秒!!!令人印象深刻的是:我不知道,为什么会有那些反对票!
int findPower(int base, int exponent){
if( 0 == exponent ) return 1;
int temp = findPower(base, exponent/2);
if(exponent % 2 == 0) return temp * temp;
return temp * temp * base;
}