一位 friend 给我上了一堂试图解决数独谜题的类(class)。问题是方法内数组的更改没有反射(reflect)在原始数组中。代码如下:
public static void solve(int array[][], int row, int col)
{
if( row > 8 )
{
printBoard(array); // this gives the correct result
return;
}
if( array[row][col] != 0 )
nextEmptyCell(array, row, col );
else
{
for( int num = 1; num < 10; num++ )
{
if(validityRowColBox(array, row, col, num))
{
array[row][col] = num;
nextEmptyCell(array, row, col);
}
}
array[row][col] = 0;
}
}
public static void nextEmptyCell(int array[][], int row, int col)
{
if( col < 8 )
solve(array, row, col + 1 );
else
solve(array, row + 1, 0 );
}
//This boolean methods will checks the validity of the number for the given row, columns and its designated box.
public static boolean validityRowColBox(int array[][], int row, int col, int num)
{
for(int c = 0; c <9; c++ )
{
if( array[row][c] == num )
return false;// It return false if the number is already exist in the given row.
}
for(int r = 0; r <9; r++ )
{
if(array[r][col] == num )
return false;// It return false if the number is already exist in the given columns.
}
row = (row / 3) * 3 ;
col = (col / 3) * 3 ;
for( int r = 0; r < 3; r++ )
{
for( int c = 0; c < 3; c++ )
{
if( array[row+r][col+c] == num )
return false;// It return false if the number is already exist in the designated box.
}
}
return true;// Otherwise true.
}
// sample input
public static int[][] easy ()
{
return new int[][]
{{0,0,0,2,6,0,7,0,1},
{6,8,0,0,7,0,0,9,0},
{1,9,0,0,0,4,5,0,0},
{8,2,0,1,0,0,0,4,0},
{0,0,4,6,0,2,9,0,0},
{0,5,0,0,0,3,0,2,8},
{0,0,9,3,0,0,0,7,4},
{0,4,0,0,5,0,0,3,6},
{7,0,3,0,1,8,0,0,0}};
}
public static void main(String args[])
{
int inputArray[][] = easy();
solve(inputArray,0,0);
printBoard(inputArray); // items still the same!
}
}
如果我调用 printBoard(array);在方法内部的函数中,数组的元素似乎发生了变化。但是当我调用 printBoard(array); 时原始数组上的 main 方法中的方法,更改将丢失,值再次恢复为原始值。我对此感到非常困惑。这些方法都不会创建新对象,因此它仍应指向 inputArray 对象。发生什么事了?
编辑:这是 printBoard() 方法
public static void printBoard(int array[][])
{
//This is the board method.
for (int row = 0; row < array.length; row++)
{
if (row % 3 == 0)//If the row is divisible by 3 then print the plus(+) and minus(-) sign.
System.out.println("+-------+-------+-------+");
for (int col = 0; col < array[row].length; col++) {
if (col % 3 == 0)// If the column is divisible by 3 then print the or(|) symbol.
System.out.print("| ");
System.out.print(array[row][col]+ " ");
}
System.out.println("|");
}
System.out.println("+-------+-------+-------+");
}
最佳答案
问题是,当您从各种递归调用返回时,有一条修改数组内容的指令(请参阅注释):
for( int num = 1; num < 10; num++ )
{
if(validityRowColBox(array, row, col, num))
{
array[row][col] = num;
nextEmptyCell(array, row, col); // after you finish you come back from here
}
}
array[row][col] = 0; // ...and this will change the solution you found
显然这会导致数组恢复到原始状态。
我没有查看程序如何工作,但如果我们发现解决方案将返回正确的数组,则避免执行该指令,例如:
public static boolean solve(int array[][], int row, int col) {
if (row > 8) {
printBoard(array);
return true;
}
if (array[row][col] != 0) {
return nextEmptyCell(array, row, col);
}
for (int num = 1; num < 10; num++) {
if (validityRowColBox(array, row, col, num)) {
array[row][col] = num;
if (nextEmptyCell(array, row, col)) {
return true; // if solution is found we just exit
}
}
}
array[row][col] = 0;
return false;
}
public static boolean nextEmptyCell(int array[][], int row, int col) {
if (col < 8) {
return solve(array, row, col + 1);
}
return solve(array, row + 1, 0);
}
关于java - 管理java中参数传递的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37240121/