簡體   English   中英

如何修復此堆棧溢出錯誤?

[英]How do I fix this stack overflow error?

所以我認為我認為java中的數獨求解器的代碼非常好,但我需要一些幫助。 當我將它嵌入main方法時,它給了我一個堆棧溢出。 問題是我的方法不知道如何扭轉並修復它的錯誤。 我需要一個布爾標志(一個與下面的代碼中使用的標志不同,實際上最好工作)或其他東西讓它知道什么時候應該轉回來,什么時候它可以再次前進並繼續解決游戲。 謝謝你提供的所有幫助

public void play(int r, int c){//this method throws the StackOverflowError
    if(needAtLoc(r,c).size()==9){
        int num=1+generator.nextInt(9);
        setCell(r,c,num,this);

    if(c<8){
    System.out.println(this);///////////////
    play(r, c+1);
    }
    else{
    play(r+1, 0);
    }
}
else{
    if(needAtLoc(r,c).size()==0){//no possible moves THIS IS THE PROBLEM LINE!!!
    if(c>0){
        play(r, c-1);//play last cell, in column to left
    }
    else{
        if(r==0){
        play(r,c);//first square, so must play again (can't go back)
        }
        else{
        play(r-1, 8);/*first cell of row so must go to previous row and 
                   the end column*/
        }
    }
    }

    else{//if there are possible moves
    int num=needAtLoc(r,c).remove(generator.nextInt(needAtLoc(r,c).size()));
    setCell(r,c,num,this);//set the value of the cell
    System.out.println(this);//////////////
    if(r==8 && c==8){//the end of the cell has been reached so must end recursive call
        return;
    }
    else{
        if(c<8){
        play(r, c+1);//normal, next cell
        }
        else{
        play(r+1, 0);/*last cell in row so we go to next one 
                   in the first column ("return" button)*/
        }       
    }
    }
}
}

我不會為你解決這個問題,而是會就如何解決這個問題提出一些建議。 9個小時是充足的。

1)您的代碼難以閱讀。 試着把它分開一點。 為變量提供有意義的明確名稱(這有助於您和其他人閱讀您的代碼)。 您可能犯了一個簡單的錯誤,清潔代碼會使這些更容易被發現。 嘗試將其分解為更小的方法,因為這將使其更具可讀性和可維護性。

2)當您進行太多嵌套方法調用並且在遞歸代碼中很常見時,會導致堆棧溢出(通常我相信)。 因此,請使您的遞歸清晰。 確保您有一個將終止的基本案例。

很抱歉不給你“答案”,但由於這聽起來像是家庭作業,我認為學習如何自己解決這個問題更有價值。 希望看起來很公平。

我認為你的問題就在於:

if(r==0)
{
    play(r,c);//first square, so must play again (can't go back)
}

那是因為你似乎沒有在這里修改任何狀態而你傳遞了相同的值,這使你首先進入這一步。 對我來說似乎是無限遞歸。

另外,請正確對齊您的代碼,因為它在未對齊時太難以閱讀,並且可能提供其他方法的一些線索。 祝好運!

您的代碼正在拋出堆棧溢出異常,因為您從未達到結束遞歸的終止條件,或者至少通過讀取代碼看到您有遞歸終止條件並不明顯。

你的代碼結構不好,因此你很難調試它。 嘗試重新構建代碼,它將幫助您重新思考問題。 另外,請評論你的代碼:)

你遞歸地調用play而不返回,看起來你每次都在函數的頂部初始化一組新的變量。

嘗試從遞歸部分中分離出初始化。 您還需要一個明確的結束條件來結束遞歸,例如(if(isBoardFilled()== true))return。

還要對它進行結構化,以便在板上添加一個數字,根據約束進行測試,如果通過,則通過刪除最后一個數字添加另一個數字(遞歸)或回溯,然后重試。

我認為你是遞歸地調用play()。試着檢查你的遞歸​​調用是否有停止條件。

我同意湯姆的意見,但這是一個提示。

沒有條件和return語句來結束遞歸調用。

我已經設法變得更簡潔,更清晰,但它仍然無法運行......我只是需要一個超越邊緣,我在家里自由。 我把這么多浪費的時間浪費在這個項目上:

public ArrayList<Integer> needAtLoc(int r, int c){
    int bc=c/3;//the column within the SudokuBoard
    int blc;

    /*The two posibilities for the column within each SudokuBlock:*/
    if(c>=0 && c<3) {
        blc=c;
    }
    else {
        blc=c%3;
    }
    int br=r/3; //the row within the SudokuBoard
    int blr;

    /*The two possiblities for the row within each SudokuBlock:*/
    if(r>=0 && r<3) {
        blr=r;
    } else {
        blr=r%3;
    }
    ArrayList<Integer> needR = new ArrayList<Integer>();
    needR=checkR(r);//
    needR.trimToSize();
    System.out.println(needR);//////////////
    ArrayList<Integer> needC=new ArrayList<Integer>();
    needC=checkC(c);
    needC.trimToSize();
    System.out.println(needC);/////////////
    ArrayList<Integer> needBl=new ArrayList<Integer>();
    needBl=this.board[br][bc].updateMissing(); //that method updates and returns an ArrayList
    needBl.trimToSize();
    ArrayList<Integer> poss=new ArrayList<Integer>();
    poss.clear();
    for(Integer e: needBl){
        if(needC.contains(e) && needR.contains(e)){
            poss.add(e);
        }
    }

    return poss;
}

//this method throws the StackOverflowError
public void play(int r, int c){
    int bc=c/3; //the column within the SudokuBoard
    int blc;
    /*The two posibilities for the column within each SudokuBlock:*/
    if(c>=0 && c<3) {
        blc=c;
    } else {
        blc=c%3;
    }
    int br=r/3; //the row within the SudokuBoard
    int blr;

    /*The two possiblities for the row within each SudokuBlock:*/
    if(r>=0 && r<3) {
        blr=r;
    } else {
        blr=r%3;
    }
    if(needAtLoc(r,c).size()==9){
        int num=1+generator.nextInt(9);
        this.board[br][bc].setValue(blr, blc, num);
        if(c<8){
            System.out.println(this);///////////////
            play(r, c+1);
        } else{
            play(r+1, 0);
        }
    } else{
        if(needAtLoc(r,c).size()==0){ //no possible moves
            if(c>0){
                bc=(c-1)/3;
                if(c>0 && c<4) {
                    blc=c-1;
                } else {
                blc = (c-1) % 3;
            }
        this.board[br][bc].setValue(blr, blc, 0);
        play(r, c-1);
    }
    else{
        blc=0;
        bc=0;
        if(r==0){
        blr=0;
        br=0;
        this.board[br][bc].setValue(blr, blc, 0);
        play(r,c);
        }
        else{
        br=(r-1)/3;
        if(r>0 && r<4) {blr=r-1;}
        else {blr=(r-1)%3;}
        this.board[br][bc].setValue(blr, blc, 0);
        play(r-1, 8);
        }
    }
    }

    else{//if there are possible moves
        int num=needAtLoc(r,c).remove(generator.nextInt(needAtLoc(r,c).size()));
        this.board[br][bc].setValue(blr, blc, num);
        System.out.println(this);//////////////
        if(r==8 && c==8){
        return;
        }
        else{
        if(c<8){
            play(r, c+1);
        }
        else{
            play(r+1, 0);
        }       
        }
    }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM