数组仅填充最后一个元素

Array fills with only last element

我正在尝试解决 8-puzzle,并且我正在尝试为空白板块的移动生成可能的棋盘配置。我将 return 这些配置放在拼图数组中,并将电路板配置作为数据。当我 运行 下面的代码时,它只存储空白瓷砖的最后一步,以防空白瓷砖有多个动作。我不确定如何阻止它覆盖以前的数组数据。

public Puzzle[] getNextPuzzle(Puzzle current) {

    //returns list of indicies representing moves as integers
    int[] ms = current.possibleMoves();
    //trims the previous move so we don't move backwards
    int[] moves = current.removeLastCase(ms);
    //return all possible configurations of puzzles based on moves
    Puzzle[] ret = new Puzzle[moves.length];
    for(int i = 0; i < ret.length; i++) {
        ret[i] = new Puzzle();
        //set array puzzle configuration to current configuration
        ret[i].setPuzzle(current.getPuzzle());
        //***System.out.Print(current.getPuzzle());
        //returns array index where blank tile is
        int num = ret[i].indexOf(0);
        //swaps the indices passed in: numbered instruction index and blank tile
        ret[i].swap(moves[i], num);
    }
    return ret;
}

Public class Puzzle {
int[] puzzle = new int[9];
public void swap(int locA, int locB) {
    int temp = this.puzzle[locB];
    this.puzzle[locB] = this.puzzle[locA];
    this.puzzle[locA] = temp;
}
public int indexOf(int n) {
    //will be out of bounds
    int ret = 10;
    for (int i = 0; i < this.puzzle.length; i++) {
        if (this.puzzle[i] == n) {
            ret = i;
        }
    }
    return ret;
}
}

示例输出:

//current configuration
1 4 2 
3 0 5 
6 7 8 
//is solvable
true
//indices of possible moves of blank tile
toRemove[0] 1
toRemove[1] 3
toRemove[2] 5
toRemove[3] 7
//indices with previous state removed for disallow of backwards
ret[0] 3
ret[1] 5
ret[2] 7
//this is being printed out where the *** is 
142305678
142035678
142530678
//what is returned in the array at the very end, expected is 3 different configurations
1 4 2 
5 3 7 
6 0 8 

1 4 2 
5 3 7 
6 0 8 

1 4 2 
5 3 7 
6 0 8 

问题是您正在创建当前拼图的浅表副本,因此您在每个循环中更改当前拼图。相反,您应该创建当前拼图的深层副本,并保持当前拼图完好无损。我不知道你的 Puzzle class 的完整实现,但你可能想检查你的构造函数和 setter 方法。

为 Puzzle 创建一个新的构造函数:

public Puzzle (int[] puzzle) { 
    //this creates a deep copy
    this.puzzle = new int[puzzle.length];
    for (int i = 0; i < puzzle.length; ++i) {
        this.puzzle[i] = puzzle[i]; 
    }        
}

然后替换以下行:

ret[i] = new Puzzle();
//set array puzzle configuration to current configuration
ret[i].setPuzzle(current.getPuzzle());

与:

ret[i] = new Puzzle(current.getPuzzle());

为了更好地解释深拷贝和浅拷贝,我推荐 this post