在某些情况下无法停止递归

时间:2012-04-05 08:20:26

标签: java recursion

我正在使用递归进行字符串(即char array)处理。在我的recursion tree中,位于child的字符串长度小于1 w.r.t其parent,并且所有相同高度的子项具有相同的字符串长度但字符不同。我想在新的string长度大于或等于旧字符串长度时停止递归,但我无法在递归之间插入此条件。使用System.exit(0)终止我的完整程序,这是我不想要的。以下是我的代码段 -

private static void getMinLen(char[] oldStr) {
    int len = oldStr.length;

    /*
     * This terminates the whole program, using break in place of
     * System.exit(0) is not effective
     */
    if (len < 2)
        System.exit(0);

    char[] newStr = new char[len - 1];

    for (int i = 0; i < len - 1; i++) {
        /*
         * Every character is matched with its next character and a new char
         * array is created having length (len-1)
         */
        getMinLen(newStr);
    }
}

实际上我把System.out.println("length=" + len);放在第3行。首先,它按递减顺序打印长度,但随后长度增加,因递归而减少。我的意思是控制台显示以下内容 -

length=6
length=5
length=4
length=3
length=2
length=1
length=3
length=3
length=2
length=1
length=4
length=3
length=2
length=1

我只想在新长度大于或等于旧长度时停止递归。

4 个答案:

答案 0 :(得分:1)

在每次不满足停止条件的getMinLen(oldStr)调用中,您多次调用getMinLen(newStr)(实际上与newStr中的元素一样多次)。从您的问题或您的第一个评论中不清楚这是否是故意的。 (你的newStr拥有与循环一样多的元素迭代的事实可能表明它不是。)

如果这不是故意的,只需将递归调用向下移动一行,即在循环的结束}之后。

如果是故意的,问题可能是您还没有理解递归是如何工作的。在某处完成停止条件的事实不会全局记录,仅与满足停止条件的单个呼叫相关。这一点本身是通过递归调用getMinLen的{​​{1}}循环来实现的(除非你以非常短的字符串开头),并且(外部)for循环继续执行所有后续调用for - 为什么要停止?为了使它停止,一个全局布尔变量会有所帮助,但是非常不优雅。或者,您可以使函数返回一个布尔值,并在每次递归调用之前检查前一个函数是否返回getMinLen。但是,您也可能会重新考虑递归方法是否真的最适合该问题。

答案 1 :(得分:0)

只需在要退出方法

的行中将System.exit(0);替换为return;

答案 2 :(得分:0)

您应该使用return

if (len < 2)
    return;

答案 3 :(得分:0)

请注意break只会“中断”循环或切换语句。要保留一个方法,你必须到达return语句或方法的结尾(如果返回类型是void,它将作为隐式return语句)。

请注意,您的方法执行以下操作:

假设初始长度为4:

1. create a new array of length 3 (4-1)
2. call the method recursively 3 times with an array of length 3
3. each new call creates an array of length 2 (3-1)
4. call the method recursively again, now 2 times and with an array of length 2
5. each new call creates an array of length 1 (2-1)
6. call the method recursively again, now once and with an array of length 1
7. each new call creates an array of length 0 (1-1)
8. those methods won't enter the loop since the condition now is `i < 0`, which is false with `i = 0`

因此,在打印每个长度时,我希望得到以下输出

4   //initial call
3   //first iteration of step 2
2   //first iteration of step 4
1   //only iteration of step 6 
2   //second iteration of step 4
1
3   //second iteration of step 2
2   
1   
2   
1
3   //third iteration of step 2
2   
1   
2   
1

如果您只想进行一次迭代然后停止,为什么要将循环放在那里?