递归调用返回的数组被覆盖。

huangapple go评论65阅读模式
英文:

Array from recursive call being overwritten

问题

我们正在制作一个使用递归方法和回溯来解决星号数独的程序。

solveIt 方法调用了 solve 方法,而 solve 方法则是递归的方法。在此之前,grid 被声明为一个 9x9 的二维数组,其中包含要填入的谜题。如果有一个解,程序必须打印出已完成的谜题;然而,如果有多个解,它只能打印出可能的解决方案数。

问题是:在 solve 方法内部,print(); 正常工作并打印出完整的谜题。然而在方法外部,它却打印出空的初始谜题。为什么会这样?当 solve 完成时,我们无法弄清楚为什么一个单独的变量(在这种情况下为 h)也会被随机覆盖。

int[][] h;
int solutionCounter = 0;

void solve() {
    int[] next = findEmptySquare();
    if (!(next[0] == -1 && next[1] == -1)) {
        if (grid[next[0]][next[1]] == 0) {
            for (int i = SUDOKU_MIN_NUMBER; i <= SUDOKU_MAX_NUMBER; i++) {
                if (!(givesConflict(next[0], next[1], i))) {
                    // 填入谜题
                    grid[next[0]][next[1]] = i;
                    // 前往下一个数字
                    solve();
                }
            }
            grid[next[0]][next[1]] = 0;
        }
    } else {
        // 这里的 print(); 正常工作
        solutionCounter++;
        h = grid.clone();
    }
}

void solveIt() {
    solve();
    if (solutionCounter > 1) {
        System.out.println(solutionCounter);
    } else {
        grid = h.clone();
        print(); // 这里打印出空谜题
    }
}
英文:

We're making a program to solve an asterisk sudoku via a recursive approach with back tracking.

The solveIt method calls the solve method which is the recursive method. grid is declared before to be a 9x9 2D array that contains the puzzle to be filled in. If there is one solution, the program must print out the completed puzzle however if there are more solutions it must only print out the number of possible solutions.

Question is: Inside of solve, print(); works just fine and prints out the complete puzzle. However outside of the method it prints out the empty initial puzzle. Why is this? We cannot figure out why a separate variable (h in this case) also gets randomly overwritten when solve completes.

int[][] h;
int solutionCounter = 0;

void solve() {
    int[] next = findEmptySquare();
    if (!(next[0] == -1 &amp;&amp; next[1] == -1)) {
        if (grid[next[0]][next[1]] == 0) {
            for (int i = SUDOKU_MIN_NUMBER; i &lt;= SUDOKU_MAX_NUMBER; i++) {
                if (!(givesConflict(next[0], next[1], i))) {
                    //fills in the puzzle
                    grid[next[0]][next[1]] = i;
                    //go to next number
                    solve();
                }
            }
            grid[next[0]][next[1]] = 0;
        }
    } else {
        //print(); here it works just fine
        solutionCounter++;
        h = grid.clone();
    }
}

void solveIt() {
    solve();
    if (solutionCounter &gt; 1) {
        System.out.println(solutionCounter);
    } else {
        grid = h.clone();
        print(); //here it prints the empty puzzle
    }
}

答案1

得分: 0

解决方案

.clone() 方法似乎只是将 h 引用指向 grid。因此,h 指向 grid 并且取得了其值,导致了上述的问题。

因此,采取了以下解决方案:

//将 grid 复制到 h 中。
for (int x = 0; x < 9; x++) {
    for (int y = 0; y < 9; y++) {
        h[x][y] = grid[x][y];
    }
}

关于 clone() 的更多信息:

https://www.geeksforgeeks.org/clone-method-in-java-2/

英文:

Solution

The .clone() method seems to simply reference h to grid. So h points to grid and takes on its values leading to the problem we were having above.

Therefore the following solution was implemented:

//copy the grid into h.
for (int x = 0; x &lt; 9; x++) {
    for (int y = 0; y &lt; 9; y++) {
        h[x][y] = grid[x][y];
    }
}

More information on clone():

https://www.geeksforgeeks.org/clone-method-in-java-2/

huangapple
  • 本文由 发表于 2020年9月28日 16:28:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/64098545.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定