最大值和最小值的递归范围输出

Posted

技术标签:

【中文标题】最大值和最小值的递归范围输出【英文标题】:Recursive Range Output from Max and Min 【发布时间】:2020-08-27 09:13:09 【问题描述】:

您好,我对 java 编码(初级)非常陌生,我正在学习如何使用递归,但我正在做一些练习,我使用最小值和最大值来获取范围。

我希望输出类似于 min 为 2 且 max 为 10 它打印 2 3 4 5 6 7 8 9 10 作为输出。它也在 min 和 max 之间打印出来,但我不知道我实际上是如何获得输出的。

代码如下:

//package methods;
public class MethodsRecursiveRange 

     public static void main(String[] args) 

          int count = 0;
          System.out.println( Range(count));                                                         

     

     public static int Range (int count) 

          int min = 2;
          int max = 10;

          for ( int i = 0; i < max ; i++) 

               System.out.println(Range(count));
               Range(count);
          
          return (0); 
     

递归函数出现stack overflow 错误。

【问题讨论】:

您需要为递归函数设置一个停止条件。否则递归函数会一直运行下去。 我该怎么做?我如何让它停止?我也应该添加哪一行? 也许可以尝试一些有用的递归问题 我认为如果你先下定决心递归方法应该是什么样子会更好。您可以在Recursion In Java 下找到一篇易于阅读的文章 @NISHANAJIHAH 您能否接受以下其中一项或解释为什么这些答案不起作用? 【参考方案1】:

在此处尝试类似下面的操作,您可以在当前 >= 最大值处停止。 请找到内联 cmets 的代码。

public class MethodsRecursiveRange 

    public static void main(String[] args) 
        Range(2,10); // Start
    

    public static int Range (int curr, int max) 
        System.out.println(curr);   // Print the current value
        if(max<=curr)              // Check if the Current value is greater or equal to Maximum limit
            return 0;               // Stop the recursion with 0 as return value
         
        return Range(++curr,max);   // Continue recursion with keeping max same, increment current value and invoke Range 

    

【讨论】:

【参考方案2】:

您使用for 循环破坏了递归的目的。

关于递归函数/方法,最重要的三件事:

    终止条件。 递归调用方法/函数的值。 处理参数的位置(递归调用之前/之后)。

按如下方式进行:

public class Main 
    public static void main(String[] args) 
        range(2, 10);
    

    public static void range(int min, int max) 
        if (max <= min - 1) // The terminating condition
            return;
        
        range(min, max - 1);// The recursive call
        System.out.print(max + " ");// Processing the parameter(s)
    

输出:

2 3 4 5 6 7 8 9 10 

附带说明,您应该始终关注Java naming conventions,例如方法的名称应该是range 而不是Range

【讨论】:

为什么有些代码使用 +1 和一些 -1 而在 System.out.print(max + " "); 使用 (max + " ") 我不明白这个 + 事情 @NISHANAJIHAH - 对于递归函数,您需要一个基本条件,之后不会有递归调用。因此,要满足基本条件,您需要不断从 min 递增到 max so +1,或者需要不断从 max 递减到 min so -1 @Arvind 如果有人调用 range(10, 2);错误地,您的代码将永远不会满足基本条件并会抛出 *** @Swetank 你所说的基本条件是什么意思? @NISHANAJIHAH 基本条件也称为终止条件,这意味着您的堆栈从哪里开始弹出,如果您没有基本条件,则递归调用将是无限的并导致堆栈内存已满并抛出堆栈溢出错误【参考方案3】:

由于您希望以递归方式从 min 打印到 max,因此对于递归函数,有一个基本条件非常重要,您的代码将从该条件停止递归调用并开始弹出堆栈。因此,在下面的代码中,您正在调用具有 min 和 max 的递归函数 Range,这里 Range 函数将每次调用,直到满足基本条件并打印您的计数,每次调用为 +1 并继续推入堆栈。一旦满足基本条件,它就会开始弹出并且代码将成功结束。

public static void main(String[] args) 
    // Range(min, max)
    Range(2, 10);


public static void Range(int count, int max) 
    System.out.println(count);

    // Base condition
    if(count >= max) return;

    // Recursive call
    Range(count + 1, max);

【讨论】:

【参考方案4】:

在递归方法中你需要做的第一件事是有一个终止条件。如果条件为真,则该方法终止。如果条件为假,则该方法会调用自身,但会更改其参数。在下面的代码中,实际上是相反的。如果条件为真,则方法调用自身,如果条件为假,则方法终止。

public class Tester 
    private static void printNum(int num, int limit) 
        if (num <= limit) 
            System.out.printf("%d ", num);
            printNum(num + 1, limit);
        
        else 
            System.out.println();
        
    

    public static void main(String[] args) 
        printNum(2, 10);
    

该方法最初是从方法main() 调用的,带有起始编号和结束编号。在最初的调用中,num = 2 和 limit = 10。这意味着条件为真,因此数字 2 打印后有一个空格。然后调用相同的方法,但第一个参数等于 3,第二个参数相同,即 10。

所以在第二次调用中,num = 3 和 limit = 10。然后该方法打印 3 并在其后添加一个空格,然后使用参数 4 和 10 调用自身。

最终,printNum() 方法被调用,num = 11 和 limit = 10 这意味着条件 [if (num &lt;= limit) ] 为 false,因此该方法不会调用自身并打印换行符。一旦方法没有调用自己,递归就会停止。

如果递归方法没有终止条件,它将继续调用自己。每次调用都需要内存来存储本地方法变量和其他东西。所以每次递归调用都意味着你的程序需要更多的内存。 Java 对可以进行的递归调用数量进行了限制。一旦超过该限制,Java 就会抛出 ***Error 并强制终止您的程序。

【讨论】:

哇,谢谢你的解释,但我仍然不明白如何停止递归循环。有没有更简单的代码,我可以很容易地理解它是如何停止的,以及你说什么来停止你需要回调它的方法的递归循环?但这与您通过调用return自己执行方法不同吗?【参考方案5】:

我知道的最简单的方法就是这样做。

如果min &lt;= max 打印最小值并使用更新的最小值调用范围 否则返回。
range(2,10);

public static void range(int min, int max) 
    if (min <= max) 
       System.out.print(min + " ");
       range(min+1, max);
    

它是这样工作的。

从主程序第一次调用。 已输入范围。 最小值 = 2,最大值 = 10 是最小值 是的,所以打印最小值为 2 现在调用范围为 3 和 10(之前的最小 +1) 输入范围 最小值 = 3,最大值 = 10 是最小值 是的,所以打印最小值是 3 现在调用范围为 4 和 10(之前的最小值 + 1) 输入范围 最小值 = 4,最大值 = 10 如果最小值 是的,所以打印最小值是 4 现在调用范围为 5 和 10(之前的最小值 + 1) 继续这种方式直到min &gt; max

最终 min > max 并且整个调用堆栈将展开并返回到调用程序。

【讨论】:

在代码中为什么一定要+1range (min+1, max); 因为我又在调用程序了。下次我调用它时,min 将是 3 并且将打印 3。然后是 4,然后是 5。当 min == max 时,它将开始通过调用堆栈返回并最终返回到第一次调用的位置。想想如果是这样。如果您简单地连续调用 range 方法 5 次,每次 min 增加 1 个值而没有递归,您将遍历这些值。但递归是程序调用自身的时候。 我用解释修改了我的答案。 我明白这有点清楚了,非常感谢@WJS

以上是关于最大值和最小值的递归范围输出的主要内容,如果未能解决你的问题,请参考以下文章

获取单行中连接的值的范围(最小值 - 最大值)

Mysql查询,范围内的最大值和最小值没有得到正确的输出

算法训练 最大值与最小值的计算

数学函数区间的最小值与最大值怎么算

寻找For循环数组C ++中最大和最小值的值

给定一个大小为 N 的数组,我需要找到在最小和最大范围内求和的最小值数