简体   繁体   English

无法理解Java中的递归

[英]Having trouble understanding recursion in Java

import java.util.Scanner; 

public class findFive {

    public static int count = 0;
    public static String result = null;

    public static void main(String[] args) {
        System.out.println("Enter a nonnegative number");
        Scanner input = new Scanner(System.in);

        int number = input.nextInt();
        countFive(number);
        System.out.println(count);
    }

    public static void countFive(int number) {
        if (number < 10) {// the base case
            if (number == 5) {
                count++;
            }
        } else { // number has two or more digits
            countFive(number / 10);
            if (number % 10 == 5) {
                count++;
            }
        }
    }
}

To put it simply, I do not understand the flow of the countFive(int number) method. 简单地说,我不了解countFive(int number)方法的流程。 I know that if the user enters 5 , then the count will simply be equal to 1. However, my confusion comes from where the method is called again inside the method with 'countFive(number/10)'. 我知道,如果用户输入5 ,则计数将简单地等于1。但是,我的困惑来自于在方法内部再次使用“ countFive(number / 10)”调用该方法的地方。

EDIT: I would appreciate if someone went through the flow of the code with a number like 552. 编辑:如果有人通过像552这样的数字进行编码,我将不胜感激。

If you want to see how this works you should step through the code in your debugger, it will be much more clear when you see it in action 如果您想了解它是如何工作的,则应该逐步调试程序中的代码,当您看到它在运行时,它将更加清晰

The method is counting how many times the digit 5 occurs in a number. 该方法计算数字5在数字中出现了多少次。 For example if you pass in the number 515 the following will happen 例如,如果您输入数字515 ,则会发生以下情况

  1. 515 is greater than 10 515大于10
  2. Call countFive(number/10) which evaluates to countFive(51) 调用计算为countFive(51) countFive(number/10) countFive(51)
  3. 51 is greater than 10 51大于10
  4. Call countFive(number/10) which evaluates to countFive(5) 调用计算为countFive(5) countFive(number/10) countFive(5)
  5. 5 is less than 10 5小于10
  6. 5 equals 5 5等于5
  7. Increment count 增量count
  8. Step out 走出去
  9. number%10 == 5 which evaluates to 1%10 == 5 - False number%10 == 5 ,其结果为1%10 == 5错误
  10. Step out 走出去
  11. number%10 == 5 which evaluates to 5%10 == 5 - True number%10 == 5 ,得出5%10 == 5
  12. Increment count 增量count

    countFive(515) | 515 greater than 10 | countFive(51) | | 51 greater than 10 | | countFive(5) | | | count++ | | 51 mod 10 does not equal 5 | 515 mod 10 equals 5 | count++

In recursion base case is created to avoid infinite calls to the same method. 在递归中,创建基本情况是为了避免无限调用同一方法。 That is defined by you below. 这是您在下面定义的。

if (number < 10) {// the base case
   if (number == 5) {
      count++;
   }
}

If this condition is satisfied, execution comes out of this method. 如果满足此条件,则执行此方法。 If this isn't true, else block is executed. 如果不正确,则执行else块。

else { // number has two or more digits
    countFive(number/10);  //This is where it is called again
    if (number%10 == 5) {
       count++;
    }
}

In this you have call to countFive(number/10) 在此您可以调用countFive(number / 10)

Well, the method counts the occurence of 5 in a number. 好吧,该方法计算出5个数字的出现次数。 For example, 5123512356 would return 3 . 例如, 5123512356将返回3

You simply use recursion to remove the last digit of the number until you have reached the highest digit ( 5 in the example on the left). 您只需使用递归来删除数字的最后一位,直到达到最高位(在左侧示例中为5 )。

Once you have reached it, it will go into number < 10 and see that it indeed is a 5. Then it will leave the method and continues with 51 (51 % 10 = 1), continues with 512 , 5123 , 51235 ( count++ ) and so on until it is through with the whole number. 一旦已经达到了它,它会进入number < 10 ,并认为它确实是一个5。然后将离开该方法,并用持续51 (51%10 = 1),与继续512512351235count++ )依此类推,直到与整数相乘为止。

To clarify: number/10 is called to reach the highest digit by removing the last digit of the original number until you cannot divide it by 10 any longer. 需要说明的是:通过删除原始数字的最后一位,直到不再不能将其除以10为止,才能调用number/10以达到最高位数。 And then the checks go through backwards. 然后支票倒退。

Let's have a look at an easier example: 5050 . 让我们看一个更简单的示例: 5050

1st call: countFive(5050) . 第一次调用: countFive(5050) 5050 > 10, so we call: 5050> 10,因此我们调用:
2nd call: countFive(5050/10) = countFive(505) . 第二次调用: countFive(5050/10) = countFive(505) Still greater than 10 仍大于10
3rd call: countFive(50) 第三次致电: countFive(50)
4th call: countFive(5) : counter++ , the number is smaller than 10 now we go backwards through these three calls (the last one is finished) 第四次调用: countFive(5)counter++ ,数字小于10现在我们向后浏览这三个调用(最后一个完成)
3rd call: 50 % 10 = 0, counter stays the same 第三次通话: 50 % 10 = 0, counter保持不变
2nd call: 505 % 10 = 5, counter++ 第二次通话: 505 % 10 = 5, counter++
1st call: 5050 % 10 = 0, counter stays the same 第一次通话: 5050 % 10 = 0, counter保持不变

Afterwards: counter = 2. 之后: counter = 2。

Let's take the input you proposed: 552 and follow the method. 让我们接受您建议的输入:552并遵循该方法。

At the beginning count is 0. 起始计数为0。

number        count     number < 10      number == 5       number % 10 == 5
-----------   -------   --------------   --------------    ------------------
552           0         false            false             false
55            0         false            false             true
              1
5             1         true             true              true
              2

And it'll return 2. Basically as you can see the method counts the number of occurrences of the digit 5 in the input. 它将返回2。基本上,您可以看到该方法对输入中数字5的出现次数进行计数。

Your base case checks if it's a digit ( < 10 ) and if so checks if the digit is 5. Otherwise, it chops the right-most digit and calls the method again, as if the input was that new number. 您的基本情况将检查它是否是一个数字( < 10 ),如果是,则检查该数字是否为5。否则,它将截断最右边的数字并再次调用该方法,就像输入的是该新数字一样。 It stops once the number is left with only a single digit. 一旦只剩下一位数字,它就会停止。

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

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