如何用Java评估递归函数?

时间:2019-06-26 11:27:48

标签: java

我是Java新手,以下代码计算a ^ b,我已经在计算机上对其进行了编译,并且可以正常工作。但是我不明白它是如何工作的? Java编译器如何计算a * power(a, b - 1),有人可以向我解释这段代码吗?

int power(int a, int b) {
    if (b < 0) {
        return 0;
    } else if (b == 0) {
        return 1;
    } else {
        return a * power(a, b - 1);
    }
}

5 个答案:

答案 0 :(得分:8)

您的函数是递归的。用一个示例演示它的工作方式可能是最简单的。

假设您要计算2 ^ 4。 因此,您致电power(2, 4);

这是评估方式(请注意,您弄错了基本情况):

power(2, 4) // b > 0, so it expands.
2 * power(2, 3)
2 * (2 * power(2, 2))
2 * (2 * (2 * power(2, 1)))
2 * (2 * (2 * (2 * power(2, 0)))) // Now, b == 0, so it evaluates to -1 
2 * (2 * (2 * (2 * -1)))
2 * (2 * (2 * -2))
2 * (2 * -4)
2 * -8
-16

答案 1 :(得分:1)

上述代码给出了错误的答案;第5行应显示为return 1;,而不是return -1;

Java通过调用来计算对power方法的调用。这里没有什么不同,因为您从power方法中调用power方法,可能会使您感到困惑。在Java中哪个还可以。

因此,让我们以power(3, 4)为例。

Java将首先检查4是否小于0。不是,请跳过该操作。然后,如果它是0。则不是,所以跳过它。然后,它将返回表达式的结果(填写变量值):return 3 * power(3, 4 - 1)。要计算该值,必须首先评估power(3, 3)

所以java ...做到了。它记得它在power(3, 4)上做的一半(它在栈上完成),现在去计算power(3, 3)。答案是评估return 3 * power(3, 2)。因此,java记住power(3, 3)完成的工作的一半,然后进行计算。答案是return 3 * power(3,1)的结果。您猜对了,记住我们的工作并再次调用电源:return 3 * power(3, 0),但最后我们退出了:方法调用power(3, 0)由第二个'if'解析,因此发生return 1;power(3, 0)成功完成!现在power(3, 1)可以完成,然后power(3, 2)可以完全完成,并返回81。

答案 2 :(得分:1)

这是递归。那是一个程序调用自己的时候。如果按所示放置打印语句,则可以看到它的工作原理。

   static int power(int a, int b) {
      if (b < 0) {
         return 0;
      }
      else if (b == 0) {
         return 1;
      }
      else {

         System.out.println("Before: a = " + a + ", b = " + b);
         int res = a * power(a, b - 1);
         System.out.println(
               "After: res = " + res + ", a = " + a + ", b = " + b);
         return res;
      }
   }

每次更改值时,如对电源的调用所示,将b减小1。然后,当b == 0时,程序开始返回,"retrieving"来自调用堆栈的每个值都要做计算。

答案 3 :(得分:1)

它称为递归函数,该函数可自行调用。为确保它不会无限调用自身(并导致堆栈溢出;),请确保至少有一个退出条件。

退出条件是不调用函数本身的返回。

以以下示例为例:3^4。实际上,3^4(3*3)*(4-1)(3*3*3)*(4-2)(3*3*3*3)*(4-3)相同。这正是您对递归所做的!

在您的情况下,重新调用是

return a * power(a, b - 1);

(与我上面显示的完全一样)

您有2个退出条件:

    if (b < 0) {
        return 0;
    } else if (b == 0) {
        return -1;
    } 

答案 4 :(得分:0)

此代码适用于递归。每个递归调用都会推入一个新的堆栈框架,然后在返回时将其弹出。

您需要检查以上代码中的基本情况。因此,当b == 0时,它应该返回1。