2012-09-23 116 views
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當我斷言如下:

​​

我的代碼如下:

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

} 

我在做什麼錯?請幫忙。 謝謝。

+0

爲什麼不這樣做的原板的內容簡單直接拷貝到新的董事會? – Dai

+0

此外,在Java中,約定是實現'Clonable'接口,並使用名爲'clone'而不是'twin'的方法。 – Dai

+0

在這種情況下,您需要在何處使用物體不可變性? – Lion

回答

3

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

而且同樣棘手的地方。您不復制您的輸入數組,而是分配對類成員屬性的引用。

+0

你是什麼意思? – newbie

+0

您已經將blocks [] []數組傳遞給構造函數,所以如果您稍後在構造函數外修改其值,則它也會在返回的Board中修改(因爲不會複製它的值而是指定相同的引用)。這可能是一種理想的行爲,而不是。 –

+0

我該如何解決這個問題? – newbie

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

這是你的問題所在。如果你想製作一個new,不要馬上改變舊版。

但是評論也是正確的。直接的複製和修改會更有意義。

+0

你是什麼意味着通過簡單的複製和修改? – newbie

+0

你可以使用'Arrays.copyOf'就像Tim建議獲得板陣列的副本,然後對其進行更改。現在你不復制它,你正在引用原來的電路板本身。 – Geobits

+0

嗨!我試過你的建議:\t int [] [] testBoardATwin = new int [dimension()] [dimension()]; testBoardATwin = Arrays.copyOf(node.board,dimension());但問題仍然是一樣的。 - – newbie

3

這就是問題所在:

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

一切都開始了好時的代碼,使新的int [] []數組,但隨後立即丟棄新的陣列和只使用了一個屬於實例twin被調用。

相反,需要發生的是node.board按索引進行索引,或者使用諸如Arrays.copyOf之類的內容。

+0

嗨!我試過\t你的建議:\t int [] [] testBoardATwin = new int [dimension()] [dimension()]; \t \t testBoardATwin = Arrays.copyOf(node.board,dimension());但問題仍然是一樣的。 – newbie

+0

嗨!我試過你的建議:\t int [] [] testBoardATwin = new int [dimension()] [dimension()]; testBoardATwin = Arrays.copyOf(node.board,dimension());但問題仍然是一樣的。 - – newbie

-1

爲了讓你必須遵循這些說明的對象:

所有你必須使課堂最後
  • 使所有領域最終和私人的
    • 第一。
    • 不要提供「setter」方法
    • 不要讓子類覆蓋方法。
    • 注意,沒有任何方法修飾狀態

    ,一個最好的參考,你可以在這裏是指在董事會的構造函數, http://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html

  • +0

    不要忘記提及需要爲返回對象(不是基元)的訪問器方法執行深層副本。 –

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