0

私はボード(3 x 3マトリックス)を持っているプログラムを書いています、そして私は論理によって特定の行と列の値を隣接する行と列と交換しなければなりません]それから私は2つのボードが欲しいです。[0,1]に0の値があり、[0,0]に[0,1]の値がある一方のボードと、[1,0]に0の値があり、[0、 0]。しかし、次のコードを実装した後、同じ値のボードが2つあり、これらの間違った値の説明を理解できません。

編集:以下に、2つの関連するクラスとそのための関連するメソッドがあります。問題は、Boardクラスのneighborメソッドにあります。ネイバーメソッドでボードを作成すると、想定どおりの動作をしないようです。

ボードクラス

public final class Board {
private final int dimen;
private final int[][] blocks;

public Board(int[][] blocks)           // construct a board from an N-by-N array of blocks
    // (where blocks[i][j] = block in row i, column j)
{
    this.dimen = blocks.length;
    this.blocks = new int[dimen][dimen];
    for (int i = 0; i < dimen; ++i) {
        for (int j = 0; j < dimen; ++j) {
            this.blocks[i][j] = blocks[i][j];
            System.out.println (this.blocks[i][j]);
        }
    }
...
...

public Iterable<Board> neighbors()     // all neighboring boards
{
    Stack<Board> neighborStack = new Stack <Board>();
    int x = 0, y = 0;
    outer : for (int i = 0; i < dimen; ++i){
        for (int j = 0; j < dimen; ++j) {
            if (this.blocks[i][j] == 0) {
                x = i;
                y = j;
                break outer;        
            }
        }
    }

    if (x == 0)
    {
        if (y == 0) {
            int tmpBlocks1[][] = Arrays.copyOf (this.blocks, this.blocks.length );
            int tmpBlocks2[][] = Arrays.copyOf (this.blocks, this.blocks.length );

            tmpBlocks1[0][0] = tmpBlocks1[0][1];
            tmpBlocks1[0][1] = 0;

            tmpBlocks2[0][0] = tmpBlocks2[1][0];
            tmpBlocks2[1][0] = 0;

            Board tmpBoard1 = new Board (tmpBlocks1);
            neighborStack.push (tmpBoard1);

            Board tmpBoard2 = new Board (tmpBlocks2);               
            neighborStack.push (tmpBoard2);

}

ソルバークラス:

public final class Solver {

private MinPQ <SearchNode> pqOriginal;
private MinPQ <SearchNode> pqTwin;
Stack <Board> shortestBoardSequence = null;
int moves = 0;

public Solver(Board initial)            // find a solution to the initial board (using the A* algorithm)
{
    pqOriginal = new MinPQ<SearchNode>();
    pqTwin = new MinPQ<SearchNode>();
    pqOriginal.insert(new SearchNode (moves, initial, null) );
    pqTwin.insert(new SearchNode (moves, initial.twin(), null) );
}

public boolean isSolvable()             // is the initial board solvable?
{
    SearchNode originalNode = null;
    SearchNode twinNode = null;
    Stack <Board> neighborBoards = null;
    while (!pqOriginal.isEmpty() || !pqTwin.isEmpty()) {

        originalNode = pqOriginal.delMin();
        // shortestBoardSequence.push(originalNode.board);

        neighborBoards = (Stack<Board>)originalNode.board.neighbors();
...
}
...
}
...
public static void main(String[] args)  // solve a slider puzzle (given below)
{
    // create initial board from file
    In in = new In(args[0]);
    int N = in.readInt();
    int[][] blocks = new int[N][N];
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
        blocks[i][j] = in.readInt();
    Board initial = new Board(blocks);

    // solve the puzzle
    Solver solver = new Solver(initial);

    // print solution to standard output
    if (!solver.isSolvable()) // SEE THE ISSOLVABLE
        StdOut.println("No solution possible");
    ..
 }
4

1 に答える 1

4

これはおそらく、2 次元配列があり、1 つの次元のみをコピーしているためです。

することによって:

int tmpBlocks1[][] = Arrays.copyOf (blocks, blocks.length );

実際には、行データではなく、行参照のみをコピーしています。あなたは以下と同等のことをしています:

int[] row0 = {0,0,0};
int[] row1 = {0,0,0};
int[] row2 = {0,0,0};
int[][] blocks = {row0, row1, row2};
int[][] tmpBlocks1 = {row0, row1, row2};

tmpBlocks同じ行を保持しますblocks

deep copy配列のa と呼ばれるものを実行する必要があります。

問題を示すコード例:

public final class Test<T> {
  int[][] blocks = {{0,1,2},{10,11,12},{20,21,22}};
  int[][] copyOfBlocks = Arrays.copyOf(blocks, blocks.length);
  int[][] deepCopyOfBlocks = {
    Arrays.copyOf(blocks[0], blocks[0].length),
    Arrays.copyOf(blocks[1], blocks[1].length),
    Arrays.copyOf(blocks[2], blocks[2].length)
  };

  public void test() {
    System.out.println("Before");
    System.out.println("Blocks: "+Arrays.deepToString(blocks));
    System.out.println("Shallow Copy: "+Arrays.deepToString(copyOfBlocks));
    System.out.println("Deep Copy: "+Arrays.deepToString(deepCopyOfBlocks));

    // Change blocks and copy and deep copy.
    blocks[0][0] = 99;
    copyOfBlocks[0][0] = 88;
    deepCopyOfBlocks[0][0] = 77;

    System.out.println("After");
    System.out.println("Blocks: "+Arrays.deepToString(blocks));
    System.out.println("Shallow Copy: "+Arrays.deepToString(copyOfBlocks));
    System.out.println("Deep Copy: "+Arrays.deepToString(deepCopyOfBlocks));
  }

  public static void main(String[] args) throws InterruptedException {
    try {
      Test test = new Test();
      test.test();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

版画:

Before
Blocks: [[0, 1, 2], [10, 11, 12], [20, 21, 22]]
Shallow Copy: [[0, 1, 2], [10, 11, 12], [20, 21, 22]]
Deep Copy: [[0, 1, 2], [10, 11, 12], [20, 21, 22]]
After
Blocks: [[88, 1, 2], [10, 11, 12], [20, 21, 22]]
Shallow Copy: [[88, 1, 2], [10, 11, 12], [20, 21, 22]]
Deep Copy: [[77, 1, 2], [10, 11, 12], [20, 21, 22]]

99 への変更は、コピーが元の行を参照していることを示す 88 への変更によって上書きされたことに注意してください。77 を使用した場合、ディープ コピーのみが影響を受けました。

于 2012-09-26T13:04:44.397 に答える