0

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

例如:

 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;
    }

}

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

4

5 回答 5

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

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

但评论也是对的。直接复制和修改会更有意义。

于 2012-09-23T05:34:43.047 回答
3

这就是问题:

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

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

相反,需要做的是node.board逐个索引,或者使用类似Arrays.copyOf.

于 2012-09-23T05:34:50.937 回答
3

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

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

于 2012-09-23T05:54:38.243 回答
0

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

  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);
于 2012-09-23T06:39:44.890 回答
-1

要制作对象,您必须遵循以下说明:

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

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

于 2012-09-23T05:40:30.967 回答