Java 使用array.clone()并更改值也会影响原始数组
我已经为一个练习编写了一个程序,该程序生成带有0(用随机数填充其余单元格)的Java 使用array.clone()并更改值也会影响原始数组,java,arrays,Java,Arrays,我已经为一个练习编写了一个程序,该程序生成带有0(用随机数填充其余单元格)的numofalidboardstocreate数独棋盘,然后求解它们。如果生成的电路板无效或不可解,它会尝试创建另一个电路板,直到获得它为止。现在让我们假设,为了简单起见,我们只需要一块带有75个空单元的电路板及其解决方案 solve()方法检查电路板是否可解,如果可解,则进行求解并返回true。现在,因为当我使用isSolvableBoard()检查for循环的if语句中每个电路板的有效性时,它反过来调用solve()
numofalidboardstocreate
数独棋盘,然后求解它们。如果生成的电路板无效或不可解,它会尝试创建另一个电路板,直到获得它为止。现在让我们假设,为了简单起见,我们只需要一块带有75个空单元的电路板及其解决方案
solve()
方法检查电路板是否可解,如果可解,则进行求解并返回true。现在,因为当我使用isSolvableBoard()
检查for循环的if语句中每个电路板的有效性时,它反过来调用solve()
,我不想求解原始电路板,因为我需要显示原始的未解决电路板,然后显示解决方案。因此,我决定使用sudokuBoard.clone()
复制原始版本,并将其用于检查,而忽略它,因为它将在评估条件后得到解决。我希望if()语句中的原始sudokuBoard
在我第一次打印时不会被解析,但输出是已解析的版本。我错过了什么
public static void main(String[] args) {
BacktrackingAlgorithm solver = new BacktrackingAlgorithm();
// Get the required input from the user
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the number of empty cells that the board should have:");
int emptyCellsPerBoard = scanner.nextInt();
System.out.println("Enter how many boards the app should create and solve:");
int numOfValidBoardsToCreate = scanner.nextInt();
// extra data to keep track of for printing purposes
int numOfInvalidBoards = 0;
int numOfUnsolvableBoards = 0;
// finding the time before the operation is executed
long start = System.currentTimeMillis();
int[][] sudokuBoard;
int[][] copyOfBoard;
for (int i = 1; i <= numOfValidBoardsToCreate; i++) {
sudokuBoard = solver.generateSudokuBoard(emptyCellsPerBoard);
// Create a copy of the board to pass to isSolvableBoard to test the condition without altering the board
copyOfBoard = sudokuBoard.clone();
if (solver.isSolvableBoard(copyOfBoard)) {
System.out.println("Board #"+i);
solver.printBoard(sudokuBoard);
System.out.println("Solution of board #"+i);
solver.solve(sudokuBoard);
solver.printBoard(sudokuBoard);
} else {
numOfUnsolvableBoards++;
numOfInvalidBoards++;
i--; // run the loop again if we haven't reached the end
}
}
// finding the time after the operation is executed
long end = System.currentTimeMillis();
//finding the time difference and converting it into seconds
float sec = (end - start) / 1000F;
// Print final message
System.out.println("Empty Cells per board: " + emptyCellsPerBoard + "\nValid boards created: " + numOfValidBoardsToCreate + "\nInvalid boards created: "
+ numOfInvalidBoards + "\nUnsolvable boards created: " + numOfUnsolvableBoards + "\nElapsed time: " + sec + " seconds");
}
}
boolean solve(int[][] board) {
for (int row = BOARD_START_INDEX; row < BOARD_SIZE; row++) {
for (int column = BOARD_START_INDEX; column < BOARD_SIZE; column++) {
if (board[row][column] == NO_VALUE) {
for (int k = MIN_VALUE; k <= MAX_VALUE; k++) {
board[row][column] = k;
if (isValid(board, row, column) && solve(board)) {
return true;
}
board[row][column] = NO_VALUE;
}
return false;
}
}
}
return true;
}
/**
* Checks if a Sudoku board is valid and solvable.
*
* @param board The given board
* @return True if it is or false otherwise.
*/
boolean isSolvableBoard(int[][] board) {
return isValidBoard(board) && solve(board);
}
/**
* Checks if the given sudoku board is valid.
*
* @param brd The 9x9 board
* @return True if it's valid or false otherwise.
*/
private boolean isValidBoard(int[][] brd) {
for (int i = BOARD_START_INDEX; i < BOARD_SIZE; i++) {
for (int j = BOARD_START_INDEX; j < BOARD_SIZE; j++) {
try {
if (!isValid(brd, i, j)) return false;
} catch (ArrayIndexOutOfBoundsException e) { // if a given cell has a value > 9, an exception is thrown, so handle it
return false;
}
}
}
return true;
}
publicstaticvoidmain(字符串[]args){
BacktrackingAlgorithm解算器=新的BacktrackingAlgorithm();
//从用户处获取所需的输入
扫描仪=新的扫描仪(System.in);
System.out.println(“输入电路板应具有的空单元数:”);
int emptyCellsPerBoard=scanner.nextInt();
System.out.println(“输入应用程序应该创建和解决的板数:”);
int numovalidboardstocreate=scanner.nextInt();
//为打印目的跟踪的额外数据
int numovalidboards=0;
int numobleboards=0;
//查找执行操作之前的时间
长启动=System.currentTimeMillis();
int[][]数独板;
int[][]电路板副本;
对于(inti=1;i9),会引发异常,因此请处理它
返回false;
}
}
}
返回true;
}
一个好的解决方案是:
for(int j=0; j <9; j++) {
copyOfBoard[j] = Arrays.copyOf(sudokuBoard[j], sudokuBoard.length); // deep copy of the subarray
}
for(int j=0;j@Sebastian)我对此进行了研究,但即使迭代并将每个单元格添加到copyOfBoard数组中似乎也不起作用是浅层副本。使用任何循环/流式处理和复制数组实例仍将只提供浅层副本。请阅读此内容以了解您的选项:。当然,总有第三方API存在,但java lang为深度副本提供的选项很少。@Digitshift不应提供数组。copyOf()perofrm一个卷影副本?或者在单元格上迭代并将值分配给一个新的不同数组int[]]newArr
?我想我已经尝试过了,但只得到了浅拷贝。让我再试一次-20分钟。是的,在2D数组上调用clone()
时,它看起来像java,不会对子数组进行深度复制:(