我正在编写一个程序,其中我有一个板(3 x 3 矩阵),并且我必须按照以下逻辑将特定行和列中的值与其相邻的行和列交换:如果我在 [ 处有 0 值, 0,0]然后我想要两 block 板。一 block 板在 [0,1] 处具有 0 值,在 [0,0] 处具有 [0,1] 值,另一 block 板在 [1,0] 处具有 0 值,在 [0,0] 处具有 [1,0] 值, 0]。但是在实现以下代码后,我有两个具有相同值的板,并且我无法理解这些错误值的任何解释。
编辑:下面我有两个相关的类和相关的方法。问题出在 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");
..
}
最佳答案
这可能是因为您有一个二维数组,而您只复制一维。
通过这样做:
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
相同的行。
您需要对数组执行所谓的深层复制
。
演示问题的示例代码:
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时仅影响深拷贝。
关于java - 两个不同的对象打印相同的属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12601881/