简体   繁体   English

如何用Java评估递归函数?

[英]How is a recursive function evaluated in Java?

I am new to Java, The following code computes a^b, I have compiled it on the computer and it is working fine. 我是Java新手,以下代码计算a ^ b,我已经在计算机上对其进行了编译,并且可以正常工作。 But I do not understand how it is working? 但是我不明白它是如何工作的? How java compiler computes a * power(a, b - 1) Can anyone please explain to me this code? 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);
    }
}

Your function is recursive. 您的函数是递归的。 It's probably easiest to demonstrate how it works with an example. 用示例演示它的工作方式可能是最简单的。

Let's say you want to compute 2^4. 假设您要计算2 ^ 4。 You therefore call power(2, 4); 因此power(2, 4);您称power(2, 4);

This is how it will be evaluated (note that you have gotten the base case wrong): 这就是评估方式(请注意,您弄错了基本情况):

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

The code as stated gives the wrong answers; 所述代码给出了错误的答案; line 5 should read return 1; 第5行应显示return 1; , not return -1; ,不return -1; .

Java computes a call to the power method by.. invoking it. Java通过调用power方法来计算对power方法的调用。 This is no different here, it might just confuse you a bit because we're calling the power method from within the power method. 这里没有什么不同,因为您从power方法中调用power方法,可能会使您感到困惑。 Which in java is fine. 在java中哪个很好。

So, let's try power(3, 4) as an example. 因此,让我们以power(3, 4)为例。

Java will first check if that 4 is below 0. It isn't, so skip that. Java将首先检查4是否小于0。不是,因此请跳过该步骤。 Then if it is 0. It is not, so skip that. 然后,如果它是0。则不是,所以跳过它。 Then it'll return the result of the expression (filling in the variable values): return 3 * power(3, 4 - 1) . 然后,它将返回表达式的结果(填充变量值): return 3 * power(3, 4 - 1) To calculate that, power(3, 3) must be evaluated first. 要计算该值,必须首先评估power(3, 3)

So java... does that. 所以java ...做到了。 It remembers its half-way done work on power(3, 4) (it does this 'on the stack') and now goes to calculate power(3, 3) . 它记得它在power(3, 4)上完成的工作(它在堆栈上完成),现在去计算power(3, 3) The answer is to evaluate return 3 * power(3, 2) . 答案是评估return 3 * power(3, 2) So, java remembers half of the work done for power(3, 3) and goes to calculate that. 因此,java记住为power(3, 3)完成的工作的一半,然后进行计算。 The answer is the result of return 3 * power(3,1) . 答案是return 3 * power(3,1) You guessed it, remember our work and invoke power yet again: return 3 * power(3, 0) but finally we're out: The method call power(3, 0) is resolved by the second 'if', thus, return 1; 您猜对了,记住我们的工作并再次调用power: return 3 * power(3, 0)但最后我们退出了:方法调用power(3, 0)由第二个'if'解析,因此, return 1; happens. 发生。 power(3, 0) successfully completed! power(3, 0)成功完成! Now power(3, 1) can complete, then power(3, 2) can complete, all the way up, and 81 is returned. 现在power(3, 1)可以完成,然后power(3, 2)可以完成,一直到最高,然后返回81。

This is recursion. 这是递归。 That is when a program calls itself. 那是一个程序调用自己的时候。 If you put print statements as shown you can see how it works. 如果按所示放置打印语句,则可以看到它的工作方式。

   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;
      }
   }

Each time thru the values are altered as shown by the call to power with b being reduced by 1. Then when b == 0 , the program starts returning, "retrieving" each value from the call stack to do the computation. 每次通过更改值,如调用电源所示,b减小1。然后,当b == 0 ,程序开始返回,从调用堆栈中"retrieving"每个值以进行计算。

It is called a recursive function, that's a function that call itself. 它被称为递归函数,即一个可以自我调用的函数。 To be sure it does not call itself infinitely (and causes a stack overflow ;)), be sure to have at least one exit condition. 为确保它不会无限地调用自身(并导致堆栈溢出 ;),请确保至少有一个退出条件。

An exit condition is one return that does not call the function itself. 退出条件是一个不调用函数本身的返回。

Take this example: 3^4 . 举个例子: 3^4 In fact, 3^4 is the same that (3*3)*(4-1) or (3*3*3)*(4-2) or (3*3*3*3)*(4-3) . 实际上3^4(3*3)*(4-1)(3*3*3)*(4-2)(3*3*3*3)*(4-3) That is exactly what you do with recursion ! 这正是您对递归所做的!

In your case, the recusrive call is 在您的情况下,重新调用是

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

(That is doing exactly what I showed above) (这正是我上面显示的内容)

And you have 2 exit conditions : 您有2个退出条件:

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

This code works on recursion. 此代码适用于递归。 Each recursive call pushes a new stack frame, then pops it when it returns. 每个递归调用将推入一个新的堆栈框架,然后在返回时将其弹出。

You need to check the base case in the above code. 您需要检查以上代码中的基本情况。 So, when b==0, it should return 1. 因此,当b == 0时,它应返回1。

step 1          : call Power(2,2)
Step 2          : go to else part a=2 and call again power(2,1)
step 3          : goto else part a=2 and call again power(2,0)
step 4          : goto else if part return -1 and go back to step 3
step 5(step 3)  : calculate 2*-1 = -2;go back to step 2
step 6(step 2)  : calculate 2*-2=-4 and finally return -4 

here step 2 to 4 same method call until match a specific condition . 在这里,第2步到第4步相同的方法调用,直到匹配特定条件为止。 it's call Recursion 这就是递归

your function have some error so it return 2^2= -4 您的函数有一些错误,所以它返回2^2= -4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM