如何摆脱递归方法调用的先前迭代?

How can one get rid of previous iteration of recursive method call?

我有一个方法可以检查用户输入的值是否在数组范围内:

public static void placeMove(int num1, int num2){
    //checking if x and y are  greater than rows and columns of a 2D array
    if(num1 > rows-1 || num2 > columns-1){
      System.out.println("This space is off the board, try again.");
      int[] values = new int[2];
      values = inputMove(); //calls inputMove method to ask user for new input
      placeMove(values[0],values[1]); //calling itself to check 
                                     //if new values are prohibited
    }
    //code to place a value in grid[num1][num2]
}

我有一个二维数组(行和列的大小因设置而异):

char[][] grid = new char[rows][columns];

当我错误检查 num1/num2 是否大于它们各自的 row/col 时,我的 placeMove 方法给了我一个 ArrayIndexOutOfBoundsException。 placeMove 再次调用 placeMove,第一次调用 placeMove 的状态被保存在堆栈中,一旦第二次调用 placeMove 的执行完成,那么第一次迭代将使用 Stack 中保存的局部变量值恢复其进一步执行,并且导致异常。我该如何防止这种情况?感谢您的帮助!

非常简单:只需 return 来自递归调用后的函数 - 或者将其他代码放入 else 块中:

    placeMove(values[0],values[1]);
    return; // <--
}
//code to place a value in grid[num1][num2]

或:

    placeMove(values[0],values[1]);
}
else
{
    //code to place a value in grid[num1][num2]
}

不过实际上,不需要递归调用,你可以用一个循环代替:

while(num1 >= rows || num2 >= columns)
// ^ instead of if         ^ (additionally changed comparison)
{
     System.out.println("This space is off the board, try again.");
     int[] values = inputMove();
     //           ^  can assign directly,
     //              (the array you created previously is just GC'ed)
     num1 = values[0];
     num2 = values[1];
}
//code to place a value in grid[num1][num2]

根据您的评论进行编辑

I have a call to inputMove() then placeMove(int num1, int num2) and finally a checkWin(int num1, int num2) method respectively in my main method. The checkWin() method uses the values returned from inputMove() method.

那么你应该placeMove内调用inputMove,而是:

int main(String[] args)
{
    int[] values = inputMove();
    while(values[0] >= rows || values[1] >= columns)
    // by the way: you do not check for NEGATIVE input!!!
    {
        System.out.println("This space is off the board, try again.");
        values = inputMove();
    }
    placeMove(values[0], values[1]); // <- won't read input any more!
    checkWin(values[0], values[1]);
}

其实这应该是一个新问题,下次再做,最好参考当前问题...

Edit2:实际上,正常检查输入是获取输入的一部分,所以我的建议是将 while 循环移动到 inputMove:

int[] inputMove()
{
    int[] values = new int[2];
    for(;;)
    {
        // read only ROW as before
        if(0 <= values[0] && values[0] < rows)
            break;
        System.out.println("row out of range");
    }
    // now the same for COLUMN
    return values;
}

Main 现在只会放弃 while 循环:

int main(String[] args)
{
    int[] values = inputMove();
    placeMove(values[0], values[1]); // <- won't read input any more!
    checkWin(values[0], values[1]);
}

这样一来,您就清楚地将相互关系最密切的事物组合在一起了。此外,对于行和列的两个单独循环,如果仅 comlumn 无效,您不会强制用户重新输入行...