Почему этот массив модифицируется? [Дубликат]

1

У меня есть массив, называемый maze который в теории должен быть модифицирован только в updateMaze(). Это потому, что это конечный результат, который я хочу вывести на консоль. Проблема заключается в том, что tempMaze изменен, а также изменен maze. Это не должно произойти. Моя первая мысль заключалась в том, что они указывают на одну и ту же ссылку в памяти, однако я проверил, и это неверно. Я должен упомянуть, что я использовал clone() при инициализации, чтобы сделать их содержимое похожим, и я не уверен, что это может быть проблемой или нет. (Хотя я думаю, что понимаю, что clone() я недостаточно осведомлен, чтобы знать, является ли это проблемой или нет.) Мой код:

public class ThreadTheMaze {
    ArrayList<Cell> result = new ArrayList<Cell>();

    private String[][] maze;
    private String[][] tempMaze;

    private int initRowPosition;
    private int initColPosition;

    private int amtOfRows;
    private int amtOfCols;

    public ThreadTheMaze(int initRow, int initCol){
        initRowPosition = initRow;
        initColPosition = initCol;
        result.add(new Cell(initRowPosition, initColPosition));
    }

    public void loadMaze(){
        try{
            Scanner in = new Scanner(new File("mazeData.txt"));
            while (in.hasNextLine()){
                amtOfCols = in.nextLine().length();
                amtOfRows++;
            }
            in.close();

            maze = new String[amtOfRows][amtOfCols];

            in = new Scanner(new File("mazeData.txt"));
            for (int r = 0; r < amtOfRows; r++){
                String line = in.nextLine();
                for (int c = 0; c < amtOfCols; c++){
                    maze[r][c] = line.substring(0,1);
                    line = line.substring(1);
                }
            }
            tempMaze = maze.clone();
        }catch (FileNotFoundException e){
            System.err.print(e);
        }
    }

    public void printMaze(){
        for (int r = 0; r < amtOfRows; r++){
            for (int c = 0; c < amtOfCols; c++){
                System.out.print(maze[r][c]);
            }
            System.out.println();
        }
    }

    public void updateMaze(){
        for (int i = 0; i < result.size(); i++){
            maze[result.get(i).getRow()][result.get(i).getColumn()] = "!";
        }
    }

    /**
     @return ArrayList of objects 'Cell' that are the solution to the maze. (Note: if no solution then returns empty ArrayList)
    */


    public void solve(Cell cell){
        tempMaze[cell.getRow()][cell.getColumn()] = "!";
        ArrayList<Cell> neighbors = getNeighbors(cell);

        if ((cell.getRow() == 0 || cell.getRow() == tempMaze.length-1) || (cell.getColumn() == 0 || cell.getColumn() == tempMaze[0].length-1)){
            return;
        }

        if ((cell.getColumn() == initColPosition && cell.getRow() == initRowPosition) && neighbors.size() < 1){
            return;
        }

        // If not in init position and has no neighbors then backtrack
        if ((cell.getColumn() != initColPosition || cell.getRow() != initRowPosition) && neighbors.size() < 1){
            result.remove(result.size()-1);
            solve(result.get(result.size()-1));
        }else if (neighbors.size() >= 1){ // If has neighbors then choose one and call the method again
            result.add(neighbors.get(0));
            solve(neighbors.get(0));
        }
    }

    /**
     @return ArrayList of objects 'Cell' that are empty and available to move to.
    */

    private ArrayList<Cell> getNeighbors(Cell cell){
        ArrayList<Cell> neighbors = new ArrayList<Cell>();
        int row = cell.getRow();
        int column = cell.getColumn();
        int[][] moveLocs = {{row-1, column}, {row+1, column}, {row, column+1}, {row, column-1}};
        for (int r = 0; r < moveLocs.length; r++){
            int tRow = moveLocs[r][0];
            int tCol = moveLocs[r][1];
            if (isValid(tRow, tCol)){
                Cell neighbor = new Cell(tRow, tCol);
                neighbors.add(neighbor);
            }
        }
        return neighbors;
    }

    public boolean isValid(int row, int col){
        if(row < 0 || row >= amtOfRows){
            return false;
        }
        if (col < 0 || col >= amtOfCols){
            return false;
        }
        if (!tempMaze[row][col].equals(" ")){
            return false;
        }
        return true;
    }

}

Класс Cell - это простой класс с некоторым простым методом get и set.

Я знаю, что это не самый краткий способ представить вам мой вопрос, но на самом деле я не могу определить место, где проблема может существовать. Благодарю.

  • 0
    @amit Это встроенный метод для массивов
Теги:
algorithm
clone
backtracking
maze

1 ответ

3
Лучший ответ

clone() неглубоко. Это означает, что следующее:

        tempMaze = maze.clone();

только клонирует первый уровень 2D-массива. Другими словами, вы получаете новый массив, содержащий те же ссылки String[] что и исходный массив.

Чтобы узнать, как это исправить, см. Раздел Как сделать глубокую копию массива 2d в Java?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню