繁体   English   中英

深度复制多维数组

[英]Deep Copy Multidimensional Array

我正在创建一个新板,该板是通过交换原始板上同一行中的两个相邻块获得的。 问题在于新板将覆盖原始板的内容。

例如:

 int[][] origBoard = { { 0, 4, 6 }, {  5, 3, 1 }, { 2, 8, 7 } };
 int[][] twinBoard = { { 0, 6, 4 }, { 5, 3, 1 }, { 2, 8, 7 } };

当我断言以下内容时,发生的事情是origBoard与twinBoard相同:

 Board B = new Board(origBoard);
 Board b = B.twin();
 assertFalse("Calling twin() modifies the original Board.", B.equals(b));

我的代码如下:

public class Board {

    private int[][] goalBoard;

    private final Node node;

    private class Node {
        private int[][] board;
        private int move;
        private Node next;
    }

    // construct a board from an N-by-N array of blocks
    // (where blocks[i][j] = block in row i, column j)
    public Board(int[][] blocks) {
        int N = blocks.length;

        goalBoard = new int[N][N];
        for (int i = 0; i < dimension(); i++) {
            for (int j = 0; j < dimension(); j++) {
                if (i == N - 1 && j == N - 1) {
                    goalBoard[i][j] = 0;
                } else {
                    goalBoard[i][j] = N * i + (j + 1);
                }
            }
        }

        // initial node
        node = new Node();
        node.board = blocks;
        node.move = 0;
        node.next = null;
    }

    // board dimension N
    public int dimension() {
        return goalBoard.length;
    }

    // a board obtained by exchanging two adjacent blocks in the same row
    public Board twin() {
        int[][] testBoardATwin = new int[dimension()][dimension()];
        testBoardATwin = node.board;
        int x = node.board[0][0];
        int y = node.board[0][1];

        // DEFAULT
        if (x != 0 && y != 0) {
            testBoardATwin[0][0] = y;
            testBoardATwin[0][1] = x;
        }
        // 2x2
        if (dimension() == 2 || y == 0) {
            if (x == 0 || y == 0) {
                x = node.board[1][0];
                y = node.board[1][1];
                testBoardATwin[1][1] = x;
                testBoardATwin[1][0] = y;
            }
        } else {
            if (x == 0) {
                testBoardATwin[0][1] = node.board[0][2];
                testBoardATwin[0][2] = y;
            }
        }

        Board board = new Board(testBoardATwin);
        return board;
    }

    // does this board equal y?
    public boolean equals(Object y) {
        Board testBoard = (Board) y;
        if (testBoard == null) {
            return false;
        }
        for (int i = 0; i < dimension(); i++) {
            for (int j = 0; j < dimension(); j++) {
                if (testBoard.node.board[i][j] != node.board[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }

}

我究竟做错了什么? 请帮忙。 谢谢。

int[][] testBoardATwin = new int[dimension()][dimension()];
testBoardATwin = node.board;

这是您的问题所在。 如果要制作一个new ,不要立即将其更改为旧的。

但是评论也是正确的。 直接复制和修改将更有意义。

这就是问题:

int[][] testBoardATwin = new int[dimension()][dimension()];
testBoardATwin = node.board;

当代码创建一个新的int [] []数组时,一切都会很好地开始,但是随后它将立即丢弃该新数组,并仅使用属于实例twin那个调用。

取而代之的是,需要对node.board进行逐个索引或使用Arrays.copyOf类的Arrays.copyOf

node = new Node(); node.board = blocks;

在Board构造函数中还有一个棘手的地方。 您不复制输入数组,而是分配对类成员属性的引用。

为了深层复制多维数组,我这样做:

  private static int[][] copy2d(int[][] nums) {
            int[][] copy = new int[nums.length][];

            for (int i = 0; i < copy.length; i++) {
                    int[] member = new int[nums[i].length];
                    System.arraycopy(nums[i], 0, member, 0, nums[i].length);
                    copy[i] = member;
            }

            return copy;
        }

    int[][] testBoardATwin = copy2d(node.board);

要创建对象,您必须遵循以下说明:

  • 首先,您必须使课程最终
  • 使所有字段均为最终字段和私有字段。
  • 不要提供“设置”方法
  • 不允许子类覆盖方法。
  • 注意,没有修改状态的方法

最好的参考之一可以参考http://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM