版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/N1neDing/article/details/82428943
题目描述:
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
解题思路1:
本题主要考察对情况的多样性的全面考量,其中,base包含正数,负数,0,exponent包括正数,负数,0,所以主要需要考虑九种情况。
其中,当base为0时,如果exponent小于0,则为输入错误(因为分母会为0),统一跟base为0的情况返回0。
exponent为0时,返回1;exponent为负数时,按照正数处理,结果取倒数;正数则正常处理。
这里有一个需要注意的点:float和double类型为浮点数,计算机表示小数都会出现误差,所以直接与数字进行==比较也会出现偏差。需要进行比较时,如果两数之间误差在极小范围内(如0.0000001),则可以认为两数相等。
参考源码1:
class Solution
{
public:
double Power(double base, int exponent)
{
double res = 1.0;
//包括base为0,exp小于0的错误情况,均返回0
if (equal_zero(base))
{
return 0.0;
}
else
{
int num = abs(exponent);
//当exponent为0时,直接返回res结果为1.0
while (num > 0)
{
res *= base;
num--;
}
if (exponent < 0)
{
res = 1 / res;
}
return res;
}
}
bool equal_zero(double num)
{
//不要再写连等了。。需要分开然后且连接。。
if (0.00000001 >= num - 0.0 && num - 0.0 >= -0.0000001)
{
return true;
}
else
{
return false;
}
}
};
解题思路2:
思路1已经·达到了全面性,但是在主函数的性能上还能进一步优化。
如2^8=2^4*2^4,2^7=2^3*2^3*2,即偶数次方为n^(exp/2)的平方,奇数次方为n^(exp/2)的平方再乘n,这样时间复杂度由O(n)转化成了O(logn)。
细节方面,使用位与&运算来代替%求余判断指数为奇数还是偶数,>>右移位运算来将指数除2操作,均可以提升效率(位运算为两个机器指令,乘除加减需要四个机器指令)。
参考源码2:
class Solution
{
double res = 1.0;
public:
double Power(double base, int exponent)
{
//包括base为0,exp小于0的错误情况,均返回0
if (equal_zero(base))
{
return 0.0;
}
int num = abs(exponent);
//当exponent为0时,直接返回res结果为1.0
res = PowerHelper(base, num);
if (exponent < 0)
{
res = 1 / res;
}
return res;
}
double PowerHelper(double base, int exponent)
{
if (exponent == 0) return 1.0;
if (exponent == 1) return base;
if (exponent & 0x1)
{
return PowerHelper(base, exponent >> 1)*PowerHelper(base, exponent >> 1)*base;
}
if (exponent & 0x1 == 0)
{
return PowerHelper(base, exponent >> 1)*PowerHelper(base, exponent >> 1);
}
return 1.0;
}
bool equal_zero(double num)
{
if (0.00000001 >= num - 0.0 && num - 0.0 >= -0.0000001)
{
return true;
}
else
{
return false;
}
}
};