Java中的幂函数使用递归

时间:2018-01-29 17:41:30

标签: java performance recursion

我正在尝试为我的Java类完成一个赋值,我们要创建一个有效的方法来解决权限(将一个基数转换为指数,由用户的输入定义)。

我已经掌握了一切,但有效的方法pow2并没有正确处理奇数指数。它将基数乘以比预期值多一个。我在这里缺少什么?

例如,如果我输入4作为我的基数而5输入我的exp,程序将吐出4096而不是1024。

import java.util.Scanner;

public class MyPow {


    public static int countGbl = 0;


    public static double raise(double base, int exp) {

        double b = base;

        for (int i = 1; i < exp; i++){
            countGbl += 1;
            base = base * b;
        }

        return base;
    }


    public static double pow1(double base, int exp) {

        if (base == 0.0) return Double.POSITIVE_INFINITY;
        else if (base == 0.0 && exp >= 0) return 0.0;
        else if (exp == 1) return base;
        else if (base > 0 && exp == 0) return 1.0;
        else{
            if (exp < 0){
                base = 1.0/base;
                exp = -exp;
            }

            if (exp % 2 == 0){
                countGbl++;
                return pow1(base, exp/2) * pow1(base, exp/2);
            }
            else {
                countGbl += 2;
                return pow1(base, exp/2) * pow1(base, exp/2) * base;
            }
        }
    }


    public static double pow2(double base, int exp) {
        double temp = raise(base, exp/2);
        double retval = temp*temp;
        if (exp % 2 == 1){
            countGbl++;
            retval *= temp;
        }
        return retval;
        }





    public static void main(String[] args) {

        Scanner s = new Scanner(System.in);

        System.out.println("Enter base: ");
        double base = Integer.parseInt(s.nextLine());
        System.out.println("Enter exp: ");
        int exp = Integer.parseInt(s.nextLine());

        System.out.println(pow2(base, exp));
        System.out.println(countGbl);

    }
}

仅仅是一个FYI,pow1方法的原因是因为我们要编写一个效率不如pow2的示例方法。

另外,请忽略countGbl。我们的教授希望我们计算方法调用期间完成的乘法次数。

2 个答案:

答案 0 :(得分:2)

看起来您正在尝试进行优化:

base exp = base exp / 2 * base exp / 2 * base

其中exp是奇数,exp/2是Java的整数除法,实际上也是数学中的一个底层函数。

但是,你在奇数情况下所做的是乘以temp的另一个因子,它已被计算为基数 exp / 2

retVal乘以base,而非temp。更改pow2

retval *= temp;

retval *= base;

此外,在raise中将exp除以2后,另一种优化方法是返回pow2方法,您可以继续使用递归,重复调用{{1}直到达到指数为1或0的基本情况。

答案 1 :(得分:1)

我勾勒出了这个问题的递归解决方案,即将赔率甚至指数直接处理为raise

public static double raise(double base, int exp) {
    if (exp == 0) {
        return 1;
    } if ((exp % 2) == 1) {

        countGbl += 1;
        return raise(base, exp-1) * base;
    } else {
        double tmp = raise(base, exp/2);

        countGbl += 1;
        return tmp * tmp;
    }
}

public static double pow2(double base, int exp) {
    return raise(base, exp);
}

这里乘法的数量相对于exp是对数的。