简体   繁体   English

我需要关于下一次递归的解释(我是初学者)

[英]I Need an explanation about the next recursion (I'm a beginner)

I know that lowkey it does 1 + 2 + 3 + 4 = 10, but I want to know how exactly it does that我知道它的低调是 1 + 2 + 3 + 4 = 10,但我想知道它是如何做到的

public class Main {

    public static int sum(int n) {
        if(n == 0) return 0;
        return sum(n - 1) + n;
    }
    
    public static void main(String[] args) {

    System.out.println(sum(4));
    
    }//main 
    
}//class
public static int sum(int n) {
    if(n == 0) return 0;
    return sum(n - 1) + n;
}

When you call sum(4) , the compiler does the following steps:当您调用sum(4)时,编译器会执行以下步骤:

  1. sum(4) = sum(3) + 4, sum(3) then calls sum(int n) and go to next step sum(4) = sum(3) + 4, sum(3) 然后调用sum(int n)和 go 进行下一步
  2. sum(3) = sum(2) + 3, sum(2) then calls sum(int n) and go to next step sum(3) = sum(2) + 3, sum(2) 然后调用sum(int n)和 go 进行下一步
  3. sum(2) = sum(1) + 2, sum(1) then calls sum(int n) and go to next step sum(2) = sum(1) + 2, sum(1) 然后调用sum(int n)和 go 进行下一步
  4. sum(1) = sum(0) + 1, sum(0) then calls sum(int n) and go to next step sum(1) = sum(0) + 1, sum(0) 然后调用sum(int n)和 go 进行下一步
  5. sum(0) = 0, return the value and bring it to previous step. sum(0) = 0,返回值并将其带到上一步。

Then with backtracking, the compiler brings the value of sum(0) to the formula sum(0) + 1 , so the value of sum(1) is 1. And so on, finally we get sum(4) is 10.然后通过回溯,编译器将sum(0)的值带入公式sum(0) + 1 ,因此sum(1)的值为 1。依此类推,最终我们得到sum(4)为 10。

The key to understanding how this recursion work is the ability to see what is happening at each recursive step.理解这种递归如何工作的关键是能够看到每个递归步骤发生了什么。 Consider a call sum(4) :考虑一个调用sum(4)

return
    sum(3) + 4
    sum(2) + 3
    sum(1) + 2
    sum(0) + 1
    return 0 in next recursive call

It should be clear how a sum of 10 is obtained for sum(4) , and may generalize to any other input.应该清楚如何为sum(4)获得 10 的总和,并且可以推广到任何其他输入。

Okay so lets understand it:好的,让我们理解它:

  1. you call the method from main method passing the argument as 4.您从传递参数为 4 的 main 方法调用该方法。
  2. It goes to method, the very first thing it checks is called as base condition in recursion.它进入方法,它检查的第一件事被称为递归中的基本条件 Here base condition is if n == 0 return 0.这里的基本条件是如果 n == 0 返回 0。
  3. We skipped the base condition since n is not yet zero.我们跳过了基本条件,因为 n 还不是零。 we go to return sum(n-1)+n that is sum(4-1)+4 .我们 go 返回 sum(n-1)+n 即sum(4-1)+4 So addition will not happen, because you made the recursive call again to sum method by decrementing the n value to n-1, in this case it is 3.因此不会发生加法,因为您通过将 n 值递减为 n-1(在本例中为 3)再次对 sum 方法进行了递归调用。
  4. You again entered the method with n =3, check the base condition which is not valid since 3,= 0, so we go to return sum (n-1)+3 , which is sum(3-1)+3您再次输入 n = 3 的方法,检查自 3 以来无效的基本条件,= 0,因此我们 go 返回 sum (n-1)+3 ,即sum(3-1)+3
  5. Next recursive call where n = 2, base condition is not valid 2,=0 , so we return sum(n-1)+2that is sum(2-1)+2 .下一次递归调用,其中 n = 2,基本条件无效 2,=0 ,因此我们返回 sum(n-1)+2 即sum(2-1)+2
  6. Next call with n = 1, base condition is not valid, we go to return sum(n-1)+1 that is sum(1-1)+1 .下一次调用 n = 1,基本条件无效,我们 go 返回 sum(n-1)+1 即sum(1-1)+1
  7. Next recursive call with n = 0, so now base condition is met, means it is time to stop the recursion and keep going back to from where we came to get the desired result.下一个 n = 0 的递归调用,所以现在满足基本条件,这意味着是时候停止递归并继续从我们来的地方返回以获得所需的结果。 So this time we returned 0 .所以这次我们返回了0
  8. Lets go back to step 6, with 0 we got and compute the addition part of sum(1-1)+1.让 go 回到步骤 6,我们得到0并计算 sum(1-1)+1 的加法部分。 You got sum(1-1) => sum(0) =.你得到了 sum(1-1) => sum(0) =。 So sum(1-1)+1 will be equal to 0+1=1所以sum(1-1)+1将等于 0+1=1
  9. One more step back with 1 as value to step 5, where we have sum(2-1)+2 = sum(1)+2 , sum(1) you know, which is 1, so we will return 1+2=3 from this recursive call.以 1 作为值再退一步到第 5 步,我们有sum(2-1)+2 = sum(1)+2 , sum(1) 你知道,这是 1,所以我们将返回 1+2= 3 从这个递归调用。
  10. One step back with value as 3, to step 4, sum(3-1)+3 = sum (2)+3 = 3+3 =6 .退一步,值为 3,到第 4 步, sum(3-1)+3 = sum (2)+3 = 3+3 =6
  11. Going one step back with 6 as value to step 3, sum(4-1)+4 = sum(3)+4 = 6+4 = 10 .以 6 作为第 3 步的值后退一步, sum(4-1)+4 = sum(3)+4 = 6+4 = 10 And that is where we started from.这就是我们开始的地方。 You got the result as 10.你得到的结果是 10。

Recursion itself is very easy to understand.递归本身很容易理解。
From a mathematical point of view, it is just a simple function call, such as your code:从数学的角度来看,它只是一个简单的 function 调用,比如你的代码:

public static int sum(int n) {
    if(n == 0) return 0;
    return sum(n - 1) + n;
}

/*
sum(0) = 0
sum(1) = 1
sum(n) = n + sum(n-1)
*/

In fact, the concept of recursion has been introduced in high school.事实上,递归的概念在高中时就已经引入。 It is the "mathematical construction method" that is often used to prove sequence problems.证明序列问题的常用方法是“数学构造法”。 The characteristics are obvious: the structure is simple and the proof is crude.特点很明显:结构简单,证明粗糙。 As long as you build the framework, you can prove it in conclusion.只要你构建了框架,你就可以在结论中证明它。 So what is a recursive "simple structure" framework?那么什么是递归的“简单结构”框架呢?

  • Initial conditions: sum(0) = 0初始条件:sum(0) = 0
  • Recursive expression: sum(n) = sum(n-1) + n递归表达式:sum(n) = sum(n-1) + n

And in fact about the sum() function, every calculation starts from sum(0) , and it is natural.而事实上关于sum() function,每次计算都是从sum(0)开始的,很自然。 Even if you are asked to calculate sum(1000), all you need is paper, pen, and time, so recursion itself is not difficult.即使你被要求计算 sum(1000),你只需要纸、笔和时间,所以递归本身并不难。
So why recursion give people an incomprehensible impression?那么为什么递归会给人一种难以理解的印象呢? That's because "recursive realization" is difficult to understand, especially using computer language to realize recursion.那是因为“递归实现”很难理解,尤其是用计算机语言来实现递归。 Because the realization is the reverse, not to let you push from the initial conditions, but to push back to the initial conditions, and the initial conditions become the exit conditions.因为实现是反过来的,不是让你从初始条件推,而是推回到初始条件,初始条件变成退出条件。

In order to be able to reverse the calculation, the computer must use the stack to store the data generated during the entire recursion process, so writing recursion will encounter stack overflow problems.为了能够逆向计算,计算机必须使用栈来存储整个递归过程中产生的数据,所以写递归会遇到栈溢出问题。 In order to achieve recursion, the human brain has to simulate the entire recursive process.为了实现递归,人脑必须模拟整个递归过程。 Unfortunately, the human brain has limited storage, and two-parameter three-layer recursion can basically make you overflow.可惜人脑存储有限,二参数三层递归基本可以让你溢出。

Therefore, the most direct way is to use paper to record the stacks in your head.所以,最直接的方法就是用纸来记录你脑海中的堆叠。 It is very mechanically painful and takes patience, but problems can often be found in the process.这是非常机械的痛苦,需要耐心,但在这个过程中经常会发现问题。

Or, go back to the definition of recursion itself.或者,go 回到递归本身的定义。

First write the architecture and then fill it in. Define the exit conditions and define the expression.先写架构,再填写。定义退出条件,定义表达式。
Second implement the code strictly according to the architecture.其次严格按照架构实现代码。 Recursive code is generally simple enough, so it is not easy to make mistakes in implementation.递归代码一般都足够简单,所以在实现中不容易出错。 Once there is a problem with the program result, the first should not be to check the code, but to check your own definition.一旦程序结果出现问题,首先不应该检查代码,而是检查自己的定义。
Meeting Infinite loop?遇到无限循环? The initial conditions are wrong or missing;初始条件错误或缺失; wrong result?结果错误? There is a problem with recursion.递归有问题。 Find out the problem, and then change the code according to the new architecture.找出问题所在,然后根据新架构更改代码。 Don't implement it without clearly defining the problem.不要在没有明确定义问题的情况下实施它。

Of course, it really doesn't work.当然,真的不行。 There is only one last resort: paper and pen.只有一个最后的手段:纸和笔。

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

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