题目描述:
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
解题方案:
第一种方案:最简单的方法就是使用Math类的
.pow方法Math.pow()
Returns the value of the first argument raised to the power of the second argument. |
计算A^n的朴素的方法就是循环n次来求幂,这样便得到O(n)时间复杂度的方法,其实大家都想得到一种优化的方法即A^n=A^(n/2)*A^(n/2),一直递归下去,其间就可以省略很多不必要的计算,得到O(logn)的方法。
下面就介绍一种用二进制方法求快速幂的运算。
我们用二进制来代替幂n,比如10的二进制为1010(二进制相信大家都会)
这里第1位和第3位(倒着数)为1,于是我们求A^10便转化为A^10=A^(2^3)*A^(2^1);这样做有什么好处呢?
我们知道对于10(1010)来说每一个二进制位都对应着A的几次幂呢?分别是A^1 A^2 A^4 A^8(也是从低位开始的);注意到这里前后的幂的关系:A^(n) = A^(n-1)*A^(n-1)(这里的n表示二进制位的位数)不是么?比如A^8=A^4*A^4, A^4=A^2*A^2....
代码表示为:
while(n) { if(n&1) //表示最后一位是1,因为我们可以通过移位来判断n的二进制位中哪些位为1 { ans *= A;//ans表示最后的结果 } A = A*A; //注意上面讲的前后二进制位对应的A的几次方的关系(移位的同时顺便计算出那一位代表的是A的几次方) n>>1; }则本题的代码:
import java.util.Scanner; /* * 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。 */ public class Power { public static void main(String[] args) { Scanner in = new Scanner(System.in); while(in.hasNext()){ double base = in.nextDouble(); int exponent1 = in.nextInt(); double result = power(base, exponent1); System.out.println(result); } } public static double power(double base, int exponent1) { double res = 1,curr = base; int exponent; if(exponent1>0){ exponent = exponent1; }else if(exponent1<0){ if(base==0) throw new RuntimeException("分母不能为0"); exponent = -exponent1; }else{// exponent1为0 return 1;// 任何数的0次方 } while(exponent!=0){ if((exponent&1)==1) res*=curr; curr*=curr;// 翻倍 exponent>>=1;//右移一位 } return exponent1>=0?res:(1/res); } }