Skip to content

Latest commit

 

History

History
114 lines (95 loc) · 3.43 KB

011-数值的整数次方.md

File metadata and controls

114 lines (95 loc) · 3.43 KB

面试题11 数值的整数次方

题目:

实现函数 double Power(double base, int exponent),求 base 的 exponent 次方。 不得使用库函数,同时不需要考虑大数问题。

package algorithm.foroffer.top20;

/**
 * Created by liyazhou on 2017/5/25.
 * 面试题11:数值的整数次方
 * 题目:
 *      实现函数 double Power(double base, int exponent),求 base 的 exponent 次方。
 *      不得使用库函数,同时不需要考虑大数问题。
 *
 * 问题:
 *      1. 指数 exponent可能为 0 或者负数
 *      2. 底数为 0 的特殊情况, 0^0 = 1,0^n = 0
 *      3. 判断 double 型底数是否为 0,虽然double 类型不是精确类型,但是Java语言支持使用等号判断
 *
 * 思路:
 *      1、exponent == 0, 返回 1
 *      2. base == 0, 返回 0
 *      3. base!=0, exponent < 0, 累乘 1/base abs(exponenet)次
 *      4. base!=0, exponent > 0, 累乘 1/base exponent 次
 *
 */
public class Test11 {

    /**
     * 一般做法
     * @param base 底数
     * @param exponent 幂次,指数
     * @return 幂运算结果
     */
    public static double power(double base, int exponent){
        if (exponent == 0) return 1.0;  // 任何数的零次幂结果均为 1
        if (base == 0) return 0.0;

        if (exponent < 0) {
            base = 1 / base;
            exponent = -exponent;
        }
        return powerWithPositiveExponent(base, exponent);
    }

    private static double powerWithPositiveExponent(double base, int exponent) {
        double result = 1.0;
        for (int i = 0; i < exponent; i++)
            result *= base;
        return result;
    }


    /**
     * 优化的方法,折半的思想,可以减少 abs(exponent)/2 次循环,
     * 如果exponent较大,可以多次折半
     * @param base 底数
     * @param exponent 幂次,指数
     * @return 幂运算结果
     */
    public static double power2(double base, int exponent){
        if (exponent == 0) return 1.0;  // 任何数的零次幂结果均为 1
        if (base == 0) return 0.0;

        if (exponent < 0) {
            base = 1 / base;
            exponent = -exponent;
        }

        double result = powerWithPositiveExponent(base, exponent>>1);  // 折半计算,减少循环次数
        result *= result;
        if ((exponent & 1) == 1) result *= base;  // 按位与 1,判断整数为奇数还是偶数
        return result;
    }

    public static void main(String[] args){
        double[] bases  =  {0, 10, -1, 5};
        int[] exponents =  {0, -5, -3, 4};
        for (int i = 0; i < bases.length; i++){
            System.out.println(String.format("power(%.6f, %d) = %.6f", bases[i], exponents[i], 
            Test11.power(bases[i], exponents[i])));
            System.out.println(String.format("power2(%.6f, %d) = %.6f", bases[i], exponents[i], 
            Test11.power2(bases[i], exponents[i])));
        }
    }
}


 // 进一步优化,使时间复杂度降为 log(n)
 // 2017年10月4日22:11:28
 public static double pow(double base, int exponent){
     if (exponent == 0) return 1;
     boolean isNegative = exponent < 0;
     if (isNegative) exponent = - exponent;

     int lgn = (int)Math.log(exponent);
     double result = base;
     for (int i = 0; i < lgn; i ++) result *= result;

     for (int j = 0; j < exponent-Math.pow(2, lgn); j ++) result *= base;

     if (isNegative) result = 1/result;
     return result;
 }