有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

LinkedList中的java值在函数clone()a 2D数组之外更改

如果尝试从solve函数外部的LinkedList“solvedBords”中读取,则保存在solvedBords中的2d数组“board”中的所有值都将变为0

但在“solved”函数中,保存在solvedBords中的二维数组“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();
        }
    }
}

共 (1) 个答案

  1. # 1 楼答案

    问题是不能将clone()用于二维数组

    在Java中,int[][] board不是真正的2D数组或矩阵,而是由1D数组组成的1D数组。换句话说,board是对象引用的数组,其中每个对象都是1Dint[]数组。当您在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不会更改