如果我试图从解算函数外的LinkedList"solvedBords"中读取,则保存在solvedBord中的2d数组"board"中的所有值都将变为0。
但在"solved"函数中,保存在solvedWords中的2d数组"board"中的所有值都是完全准确的。
这是由于递归吗?任何解释都将不胜感激
主类
public class main {
public static void main(String[] arg){
testQueen N = new testQueen();
}
}
测试级
import javax.swing.*;
import java.util.LinkedList;
public class testQueen {
private int[][] board;
private LinkedList<int[][]> solvedBords = new LinkedList<>();
private static int boardSize = 0;
testQueen() {
boardSize = 8;
board = new int[boardSize][boardSize];
start();
}
void start() {
solve(0);
System.out.println("solvedBords = " + solvedBords.size());
while (!solvedBords.isEmpty()) {
System.out.println("this is in the start funktion");
printBord(solvedBords.pop());
System.out.println("");
}
}
void solve(int row) {
if (row == boardSize) {
System.out.println("this is in the solve function: ");
printBord(board);
System.out.println("");
solvedBords.add(board.clone()); // 2d array “board” that is saved in
// solvedBords
/*
* System.out.println("solvedBords = " + solvedBords.size());
* while(!solvedBords.isEmpty()){ printBord(solvedBords.pop());
* System.out.println(""); }
*/
return;
}
for (int colum = 0; colum < boardSize; colum++) {
if (validMove(row, colum)) {
paceQueen(row, colum, 0);
solve(row + 1);
paceQueen(row, colum, 1);
}
}
}
boolean validMove(int x, int y) {
for (int i = 0; i < boardSize; i++) {
if (get(x, i) > 0) {
return false;
}
if (get(i, y) > 0) {
return false;
}
if (get(x - i, y - i) > 0) {
return false;
}
if (get(x - i, y + i) > 0) {
return false;
}
if (get(x + i, y - i) > 0) {
return false;
}
if (get(x + i, y + i) > 0) {
return false;
}
}
return true;
}
/**
*
* if type == 1 the queen is going to be placed in row x and column y
*
* else if type == 0 the queen is going to be removed from row x column y
*
* @param x
* is the row
* @param y
* is the column
* @param type
* is 0 or 1
*/
void paceQueen(int x, int y, int type) {
if (type == 0) {
board[x][y] = 1;
} else if (type == 1) {
board[x][y] = 0;
}
}
int get(int x, int y) {
if (x < 0 || y < 0 || x >= boardSize || y >= boardSize) {
return -1;
}
return board[x][y];
}
void printBord(int[][] board) {
for (int i = 0; i < boardSize; i++) {
for (int j = 0; j < boardSize; j++) {
if (board[i][j] > 0) {
System.out.print("[1]");
} else if (board[i][j] == 0) {
System.out.print("[0]");
}
}
System.out.println();
}
}
}
问题是不能将clone()
与2D数组一起使用。
在Java中,int[][] board
是,而不是真正的2D阵列或矩阵——它是1D阵列的1D阵列。换句话说,board
是对象引用的数组,其中每个对象是1D int[]
数组。当您在array[][]
上调用clone()
时,它会执行浅拷贝-外部数组被克隆,但内部数组不是-它们只是对相同数据的新引用。这样做的结果是,每次更改board
中的值时,也会更改solvedBoards
中的所有内容。
一种解决方案是编写一个深度复制函数clone2dArray
,并用clone2dArray()
:替换对clone()
的调用
int[][] clone2dArray(int[][] original) {
int [][] cloned = new int[original.length][];
for (int i = 0; i < original.length; i++) {
cloned[i] = original[i].clone();
}
return cloned;
}
void solve(int row) {
...
solvedBords.add(clone2dArray(board)); // 2d array “board” that is saved
...
}
另一个也许更好的解决方案可能是创建一个矩阵类来存储您的电路板。
还要注意,您正在递归调用solve()
,当您从调用返回时,board
将发生更改。这可能不是你所期望的。您可以将board
作为参数传递给solve
,确保始终将其作为clone2dArray()
副本传递。将确保从递归调用返回时board
不会更改。