如何将这个简单的for循环转换为递归

时间:2015-11-08 13:34:48

标签: java for-loop recursion

 import java.util.Scanner;

 public class ForloopToRecursion {
 public static void main(String[] args) {
 Scanner input = new Scanner(System.in);

 System.out.println("Enter number of sips");
 int sip = input.nextInt();
 if(sip>=10){
   int n =sip;
   for (int i = 0 ;i <sip; i++){

     System.out.println("sip of a coffee"+n);
     n--;
   }
  }
 }
}

我需要将此代码转换为递归。程序应该要求用户输入sip数,然后使用递归,每次打印以下字符串

"sip of a coffee".

2 个答案:

答案 0 :(得分:2)

@Dima Maligin是绝对正确的。这是解释递归核心概念的基本示例。理解这将有助于理解更复杂的递归算法。

对@Franscisco Hernandez给出的答案进行一点扩展:

递归的核心概念是将问题减少到同一问题的较小实例,并从部分结果中构造结果。 把它放在编程术语中:你编写一个通过调用自身来解决问题的函数。

这需要两个特定部分(松散地来自wikipedia):

  1. 可以停止递归的基本情况。我也听过这个术语的地板或锚。这必须是您可以轻松解决的问题的原子版本。
  2. 一组允许您将问题缩减为重复步骤的规则。
  3. 让我们将此应用于您的示例。你有一杯咖啡,至少含有10口咖啡。你必须全部啜饮它们(这里没有口袋妖怪的参考。)所以如果不再有啜饮,你可以停下来。这是基本情况。在达到这一点之前,我们一口一口地喝一口咖啡。在循环中,每个sip在循环的一次迭代中完成。这里我们使用递归规则来执行此操作。还是啜饮了吗?啜一口,继续喝一口。在某些时候(特别是在用户通过扫描仪输入的数字之后),您将会用完啜饮并进入基本案例。

    在Java代码中,这将如下所示:

    import java.util.Scanner;
    
    public class ForloopToRecursion {
    
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
    
            System.out.println("Enter number of sips");
            int sip = input.nextInt();
            if(sip>=10){
                sipCoffee(sip);
            }
        }
    
        public static void sipCoffee(int sipsRemaining){
    
            // This is your recursions base
            // When you reach 0 remaining sips
            // you immediately exit the function
            // without doing anything
            // Note that the test == 0 would also suffice
            // here, but 
            if (sipsRemaining <= 0){
                return; 
            }
    
            // If you reached this part of the code
            // you have more than one sip remaining 
            System.out.println("Take a sip of coffee.");
    
            // To reduce the number of sips you call a
            // new instance of the sipCoffee function
            // with a reduced number of sipsRemaining
            // Note that you are calling the function from
            // within itself. This is the recursion step.
            sipCoffee(sipsRemaining-1);
        } // termination
    
    }
    

    现在到了有趣的部分。 Java函数终止(即完成时)到达最后一个结束大括号(标记为``terminate in the code) of the function. Now notice that when you enter the function with sipsRemaining&gt; 0 you call another instance of sipCoffee`。你调用的实例没有已经终止了,因为第二个电话尚未终止。这会累积直到您遇到基本情况。

    想象一下这样。每个对sipCoffee的调用都会在内存中持续存在,直到它们终止。它们只能在它们运行结束时终止,并且只有在达到基本情况时才会发生。然后焦点跳回sipCoffee(1),可以终止,然后sipCoffee(2)可以终止等。

    ...
    sipCoffee(5)
    |
    | sipCoffee(4)
    | |
    | | sipCoffee(3)
    | | |
    | | | sipCoffee(2)
    | | | |
    | | | | sipCoffee(1)
    | | | | |
    | | | | | sipCoffee(0)
    | | | | | |
    | | | | | * terminates
    | | | | |
    | | | | * terminates
    | | | |
    | | | * terminates
    | | |
    | | * terminates
    | |
    | * terminates
    |
    * terminates
    

    我希望这会有所帮助。当记住这是一个典型的编程101任务时,将会有更多涉及递归的任务。在你达到像快速排序这样的花哨的东西之前,你想要理解这一点。玩得开心:))

答案 1 :(得分:0)

试试这个

package a;

import java.util.Scanner;

public class ForloopToRecursion {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        System.out.println("Enter number of sips");
        int sip = input.nextInt();

        if (sip >= 10) {
            int n = sip;
            recursion(n);
            /*for (int i = 0; i < sip; i++) {

                System.out.println("sip of a coffee" + n);
                n--;
            }*/
        }
    }

    private static void recursion(int sip) {

        if (sip == 0) {
            return;
        }

        System.out.println("sip of a coffee" + sip);

        recursion(sip-1);
    }
}