使用array.clone()并更改值也会影响原始数组

时间:2020-10-03 18:28:05

标签: java arrays

我为练习编写了一个程序,该程序生成numOfValidBoardsToCreate个数独板,其中emptyCellsPerBoard个单元格的个数为0(用随机数填充其余部分),然后求解它们。如果生成的板无效或可解决,它将尝试创建另一个板,直到获得为止。现在,为了简单起见,我们只请求一个带有 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;
}

1 个答案:

答案 0 :(得分:0)

下面是一个好的解决方案:

for(int j=0; j <9; j++) {
  copyOfBoard[j] = Arrays.copyOf(sudokuBoard[j], sudokuBoard.length); // deep copy of the subarray
}

基本上可以对2D数组的每个子数组进行深层复制。