问题描述:
double power(double x, int n)的计算, n 可以是正也可以是负。
问题分析:
注意计算效率,避免重复计算。
伪代码:
下面代码不正确
double power(double x, int n)
{
if (n == 0) return 1;
if (n > 0)
{
double tmp = power(x, n >> 1);
double retVal = n & 1 ? tmp * tmp * x : tmp * tmp;
return retVal;
}
else
{
double tmp = power(x, -1 * n);
return (double)1.0 / tmp;
}
}
实例代码:
下面代码正确,易于理解,运行时间比较慢。对于上面问题的修正在于递归返回的地方,
n == 0 和 n == 1 是两种不同的情况不能进行合并。
在 n > 1的时候可以考虑采用迭代的方式来提高运行的效率。要做到O(lgn)复杂度的迭代
需要花费一番功夫。
double pow(double x, int n)
{
if (n == 0) return 1.0;
if (n == 1) return x;
if (n > 1)
{
double tmp = pow(x, n >> 1);
double ret = n & 1 ? tmp * tmp * x : tmp * tmp;
return ret;
}
else
{
double tmp = pow(x, -n - 1); /* 此处处理 INT_MIN 的情况 */
return (double)1.0 /( tmp * x);
}
}
迭代的版本:
1. n < 0 转换成为 n > 0 的情况进行处理。
2. -n - 1 在于处理INT_MIN的情况。
3. 迭代实现了O(lgn)复杂度的迭代。
4. cur1 记录正常的累乘结果
5. cur2 记录奇数的情况下(2 * k + 1)中那个 1 的累乘结果,与上一层的结果有关。
double pow(double x, int n)
{
if (n == 0)
{ return 1; }
double cur1, cur2;
for (cur1 = x, cur2 = 1; n > 1; cur1 *= cur1, n >>= 1)
{
if (n & 1) cur2 = cur2 * cur1;
}
if (n < 0)
{ return 1 / (x * pow(x, -n - 1)); }
return cur1 * cur2;
}