一,问题提出
问题: 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
- 满足以下要求:时间限制:1秒 空间限制:32768K
方法一:简单的循环
- 举个列子:2 ^ 3 等于8, 也就是 2 * 2 * 2, 也就意味着 2 ^ 3要给2本身乘以两个2,用while和for循环可以实现这个功能;
- 代码实现如下
double Power(double base, int exponent)//函数名
{
int temp = base;//定义一个变量赋值为base,
while(--exponent)
base *= temp;//base乘以初始值
return base;
}
- 这个代码有缺陷,只能实现大于0次方的那一部分,小于等于0的次方,不能实现,改代码如下
double Power(double base, int exponent)//函数名
{
double temp = base;
if(exponent > 0)//先对传进来的参数进行判断,大于0 和小于0 等于0 处理方式不同
{
while(--exponent)
base *= temp;
return base;
}
else if(exponent < 0)
{
while(++exponent)
base *= temp;
return 1 / base;
}
else
return 1;
}
- 以上代码可以处理所有情况,但是运行起来很慢,已经超过一秒了,不满足要求,
方法二:简单的递归
- 任何数的0次方都等于1,任何数的1次方都等于他本身,可以通过递归的方法,把大的事件化成小的事件,比如22222 = 162,—>= 82*2,就这样以此化简,把大的事件化简成小事件,
double Power(double base, int exponent)//函数名
{
if(exponent == 0)
return 1;
else if(exponent == 1)
return base;
else
return base * Power(base, exponent - 1);//返回base 乘以之前的函数值
}
- 这个方法还是类似于之前的方式,只能处理正数的次方,负数次方处理不了,这也是有缺陷的方法,而且也不满足要求,空间超出了,
方法三:二分法递归
- 举例来说,2 ^ 8 可以分成 2 ^ 4* 2 ^ 4, 然后2 ^ 4也可以分成2 ^ 2*2 ^ 2,这样依次分下去,就会把一个很大的数据化成很多小的数据相乘,大大减小了递归的深度,
- 处理负数次方,可以按照之前的方法做,返回 1/ base,
- 代码如下:
double Power(double base, int exponent)//函数名
{
if(exponent > 0)
{
if(exponent == 1)
return base;
else if(exponent % 2 == 0)
return Power(base, exponent / 2) * Power(base, exponent /2);
else
return Power(base, exponent / 2) * Power(base, exponent /2 + 1);
}
else
{
if(exponent == 0)
return 1;
else
return 1 / Power(0 - exponent);
}
}
- 这个方法是满足要求的,我觉得这个方法的精髓就在于,把大量的次方数,分半,然后在相乘,最终的数据大小不变,但是从中减少了递归的深度,如果按照往常的递归方式,递归深度很多,大大增加了运行时间,性能很低,