数组仅填充最后一个元素

时间:2017-04-27 07:00:34

标签: java arrays object shallow-copy

我正在尝试解决8-puzzle,并且我正在尝试为空白磁贴的移动生成可能的板配置。我将把这些配置返回到拼图数组中,并将板配置作为数据。当我在下面运行我的代码时,它只会在空白磁贴有多个移动的情况下存储空白磁贴的最后一次移动。我不确定如何阻止它覆盖以前的数组数据。

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 

1 个答案:

答案 0 :(得分:1)

问题在于您正在创建当前拼图的浅表副本,因此您可以在每个循环中更改当前拼图。您应该创建当前拼图的深层副本,并保持当前拼图完好无损。我不知道你的Puzzle类的完整实现,但你可能想检查你的构造函数和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