Java 基于递归算法的stackoverflowerr

Java 基于递归算法的stackoverflowerr,java,algorithm,recursion,stack-overflow,Java,Algorithm,Recursion,Stack Overflow,我试图编写一个递归算法,以便为一个名为kakuro的游戏生成一个有效的棋盘(唯一的解决方案)。 当执行程序时,我总是得到一个StackOverflower错误。我试着调试我的代码,它按预期工作,但它突然在非递归方法中崩溃。我一直在互联网上读到关于这个问题的文章,我已经检查过我没有使用相同的参数进行两次递归调用。该算法对某些正方形尝试不同的值,然后(当每个正方形都有自己的值时,它应该尝试这些正方形的所有可能的值组合)对其进行求解,以查看它是否有唯一的解 private boolean gener

我试图编写一个递归算法,以便为一个名为kakuro的游戏生成一个有效的棋盘(唯一的解决方案)。 当执行程序时,我总是得到一个StackOverflower错误。我试着调试我的代码,它按预期工作,但它突然在非递归方法中崩溃。我一直在互联网上读到关于这个问题的文章,我已经检查过我没有使用相同的参数进行两次递归调用。该算法对某些正方形尝试不同的值,然后(当每个正方形都有自己的值时,它应该尝试这些正方形的所有可能的值组合)对其进行求解,以查看它是否有唯一的解

 private boolean generarKakuroRecursivo(ArrayList<Negra> noColocados, Casella[][] tablero){
        if (noColocados.size() == 0 ){
            System.out.println(getStringTablero());
            if (kakuroUnico(tablero)){
                this.tauler = tablero;
                return true;
            }
            else return false; 
        }
        
        Negra casillaNegra = noColocados.get(0);

        boolean fila = casillaNegra.getFila() == 0 && casillaNegra.getCoords().getElement1()+1 < dimensio && this.tauler[casillaNegra.getCoords().getElement0()][casillaNegra.getCoords().getElement1()+1].getTipus() == 'B';
        boolean columna = casillaNegra.getColumna() == 0 && casillaNegra.getCoords().getElement0()+1 < dimensio && this.tauler[casillaNegra.getCoords().getElement0()+1][casillaNegra.getCoords().getElement1()].getTipus() == 'B';
        ArrayList <Pair<Integer, ArrayList<ArrayList<Integer>> >> posibilidadesNegra = calcularPosibilidades(casillaNegra);

        //CALCULAMOS LOS POSIBLES NUMEROS PARA LA CASILLA NEGRA QUE HEMOS COGIDO

        int index1 = casillaNegra.getCoords().getElement0(), index2 = casillaNegra.getCoords().getElement1();
        for (Pair<Integer, ArrayList<ArrayList<Integer>> > posibilidad : posibilidadesNegra){
            int valor = posibilidad.getElement0();
            if (fila && columna){
                colocarNegra(((Negra)tablero[index1][index2]), valor, true);
                noColocados.get(0).setNumFil(valor); //poner fila =false
            } //actualizar restricciones
            else if(fila){
                colocarNegra(((Negra)tablero[index1][index2]), valor, true);
                noColocados.remove(0);
            }
            else if (columna){
                colocarNegra(((Negra)tablero[index1][index2]), valor, false);
                noColocados.remove(0);
            }
            if (generarKakuroRecursivo(noColocados, tablero)) return true;
            else{
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     if (!noColocados.contains(casillaNegra)) noColocados.add(casillaNegra);
                if (fila){
                    retirarNegra((Negra)tablero[index1][index2],true);
                    if (!noColocados.contains(casillaNegra)) noColocados.add(casillaNegra);
                }

                else if (columna) {
                    retirarNegra((Negra)tablero[index1][index2], false);
                    if (!noColocados.contains(casillaNegra)) noColocados.add(casillaNegra);
                }

            }
        } //Caso recursivo

        //PROBAMOS RECURSIVAMENTE TODAS LAS OPCIONES

        return false;
}
private boolean generarkakurocursivo(ArrayList noColocados,Casella[]tablero){
if(noColocados.size()=0){
System.out.println(getStringTablero());
if(卡库鲁尼科(表){
this.tauler=tablero;
返回true;
}
否则返回false;
}
Negra casillaNegra=noColocados.get(0);
布尔fila=casillaNegra.getFila()==0&&casillaNegra.getCoords().getElement1()+1ArrayListStackOverflowerError仅表示堆栈中没有空间用于新帧。在您的情况下,递归调用仍然会填满大部分堆栈,但由于该方法调用自身以外的其他方法,这些方法也会耗尽堆栈


例如,如果递归方法仅调用自身,则调用该方法时堆栈将始终耗尽。

StackOverflowerError仅表示堆栈中没有空间可用于新帧。在您的情况下,递归调用仍会填满堆栈的大部分,但由于该方法调用其他方法,因此它们本身也会耗尽堆栈


例如,如果您的递归方法仅调用自身,则调用该方法时堆栈将始终耗尽。

那么…我如何解决此问题?递归算法调用的方法是否是一个问题?不,根本问题是堆栈大小不足以满足所需的递归量。理想情况下,您应该编写使用循环而不是递归的算法。实际上,您可以通过增加堆栈大小来解决问题。我尝试将堆栈大小从2048MB增加到16384MB,但程序仍然在完全相同的部分崩溃。如果堆栈大小不同,如何可能在相同的递归调用中触发StackOverflower错误?因为程序递归,大部分堆栈跟踪将是一个模式,反复重复。你有没有估计递归需要有多深才能得到解决方案?那么…我如何解决这个问题?递归算法调用的方法是一个问题吗?不,根本问题是堆栈大小不足以满足am需要大量递归。理想情况下,您应该重写算法以使用循环而不是递归。实际上,您可以通过增加堆栈大小来避免。我尝试将堆栈大小从2048MB增加到16384MB,但程序仍然在完全相同的部分崩溃。如何可能在相同的递归中触发StackOverflower错误如果堆栈大小不同,则rsive调用?由于程序递归,大多数堆栈跟踪将是一种模式,反复重复。您是否估计递归需要多深才能找到解决方案?