【问题标题】:values in LinkedList changed outside of the function, clone() a 2D arraysLinkedList 中的值在函数之外更改,clone() 是一个二维数组
【发布时间】:2015-09-22 19:27:21
【问题描述】:

如果我尝试从求解函数之外的 LinkedList “solvedBords”中读取保存在solvedBords 中的二维数组“board”中的所有值。

但在“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();
        }
    }
}

【问题讨论】:

  • 你能修正你的缩进吗?
  • 尽力修复,无法粘贴代码。
  • 您的帖子不可读,请使用标点符号和正确的语法。

标签: java arrays recursion multidimensional-array linked-list


【解决方案1】:

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

在 Java 中,int[][] board 不是真正的二维数组或矩阵 - 它是一维数组的一维数组。换句话说,board 是一个对象引用数组,其中每个对象都是一个一维 int[] 数组。当您在 array[][] 上调用 clone() 时,它会执行 浅复制 - 外部数组被克隆,但内部数组不是 - 它们只是对相同数据的新引用。这样做的结果是,每次您更改 board 中的值时,您也会更改 solvedBoards 中的所有内容。

一种解决方案是编写一个深拷贝函数clone2dArray 并将您对clone() 的调用替换为clone2dArray()

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 不会更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-08
    • 1970-01-01
    • 2015-03-22
    • 2013-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多