2个同类对象被另一个同类对象错误实例化

时间:2017-05-10 14:55:30

标签: java

我目前正在使用A *算法(汉明)方法实现八难题,并提供了代码:

public class Board
{
int board[][];

public Board()
{
    board = new int[3][3];
}

public void initialise(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9)
{
    //first row
    board[0][0] = n1;
    board[0][1] = n2;
    board[0][2] = n3;

    //second row
    board[1][0] = n4;
    board[1][1] = n5;
    board[1][2] = n6;

    //third row
    board[2][0] = n7;
    board[2][1] = n8;
    board[2][2] = n9;
}


public int states_out_of_order()
{
    int count = 0;

    for(int i = 0; i < 3; i++)
    {
        //Checking if first row is
        //1     2     3
        if(i==0)
        {
            if(board[i][0]!=1)
            {
                count++;
            }

            if(board[i][1]!=2)
            {
                count++;
            }

            if(board[i][2]!=3)
            {
                count++;
            }
        }

        //Checking if second row is
        //4     5     6
        if(i==1)
        {
            if(board[i][0]!=4)
            {
                count++;
            }

            if(board[i][1]!=5)
            {
                count++;
            }

            if(board[i][2]!=6)
            {
                count++;
            }
        }

        //Checking if second row is
        //7     8     0
        if(i==2)
        {
            if(board[i][0]!=7)
            {
                count++;
            }

            if(board[i][1]!=8)
            {
                count++;
            }

            if(board[i][2]!=9)
            {
                count++;
            }
        }
    }
    return count;
}

public boolean GoalStateCheck()
{
    //Checking first row
    if(board[0][0]!=1)
    {
        return false;
    }

    if(board[0][1]!=2)
    {
        return false;
    }

    if(board[0][2]!=3)
    {
        return false;
    }

    //Checking second row
    if(board[1][0]!=4)
    {
        return false;
    }

    if(board[1][1]!=5)
    {
        return false;
    }

    if(board[1][2]!=6)
    {
        return false;
    }

    //Checking third row
    if(board[2][0]!=7)
    {
        return false;
    }

    if(board[2][1]!=8)
    {
        return false;
    }

    if(board[2][2]!=0)
    {
        return false;
    }

    return true;
}

public void printBoard()
{
    System.out.print(board[0][0] + " " + board[0][1] + " " + board[0][2]);
    System.out.println();
    System.out.print(board[1][0] + " " + board[1][1] + " " + board[1][2]);
    System.out.println();
    System.out.print(board[2][0] + " " + board[2][1] + " " + board[2][2]);
    System.out.println();
}
}

现在解算器类

import java.util.ArrayList;

public class Solver
{
ArrayList<Board> list;
int steps;

public Solver()
{
    list = new ArrayList<Board>();
    steps = 0;
}

public Board SwapStates(Board b, int a[][], int r1, int c1, int r2, int c2)
{
    int temp = a[r1][c1];
    a[r1][c1] = a[r2][c2];
    a[r2][c2] = temp;

    return b;
}

//Find the board in ArrayList according the number of states out of order
public Board findBoard(int num)
{
    for(int i = 0; i < list.size(); i++)
    {
        if(num == list.get(i).states_out_of_order())
        {
            return list.get(i);
        }
    }
    return null;
}

//Choose the puzzle state with minimum states that are out of order
public int min()
{
    int n = 10;

    for(int i = 0; i < list.size(); i++)
    {
        if(list.get(i).states_out_of_order() < n)
        {
            n = list.get(i).states_out_of_order();
        }
    }
    return n;
}

//Find the board in ArrayList and remove it
public void matchRemove(Board b)
{
    for(int i = 0; i < list.size(); i++)
    {
        if(b == list.get(i))
        {
            list.remove(list.get(i));
            break;
        }
    }
}

public void Hamming(Board b)
{
    boolean solved = b.GoalStateCheck();

    while(!solved)
    {
        if(b.board[0][0] == 0)
        {
            //Pointer to original board
            final Board ptr = b;

            Board b1 = ptr;
            Board b2 = ptr;

            //Check move #1 from original state
            b1 = SwapStates(b1, b1.board,0,0,0,1);

            //Check move #2 from original state
            //Problem is that it is not swapping ptr but rather its swapping b1. why?
            b2 = SwapStates(b2, b2.board,0,0,1,0);

            //Add the moves to the Arraylist
            list.add(b1);
            list.add(b2);

            //Find the board with minimum number of states out of order and remove it frm list
            int n = min();
            Board temp = findBoard(n);
            matchRemove(temp);

            //Assign removed board as optimum move
            b = temp;
            steps++;
            b.printBoard();
        }

        else if(b.board[0][1] == 0)
        {

        }

        else if(b.board[0][2] == 0)
        {

        }

        else if(b.board[1][0] == 0)
        {

        }

        else if(b.board[1][1] == 0)
        {

        }

        else if(b.board[1][2] == 0)
        {

        }

        else if(b.board[2][0] == 0)
        {

        }

        else if(b.board[2][1] == 0)
        {

        }

        else if(b.board[2][2] == 0)
        {

        }

        else
        {
            System.out.println("Board is not in its proper form");
            break;
        }
    }
    /*System.out.println("Goal State has been achieved!!");
    System.out.println("It took " + steps + " moves");
    b.printBoard();*/
}
}

在我的Solver类的Hamming函数中,在第一个if语句中我有这一行

final Board ptr = b;
Board b1 = ptr;
Board b2 = ptr;

然而,在这两行:

            //Check move #1 from original state
            b1 = SwapStates(b1, b1.board,0,0,0,1);

            //Check move #2 from original state
            //Problem is that it is not swapping ptr but rather its swapping b1. why?
            b2 = SwapStates(b2, b2.board,0,0,1,0);

b2正在使用b1的交换状态而不是我想要使用的原始ptr。为什么呢?

1 个答案:

答案 0 :(得分:1)

当你写完

final Board ptr = b;
Board b1 = ptr;
Board b2 = ptr;

没有创建名为b的{​​{1}}的不可变副本以及名为ptrptr的{​​{1}}的两个可变副本}。

您只需创建3个对同一对象的引用。使用任何4个引用对对象进行的任何修改都将以相同的方式影响对象,从而更改所有4个引用的可见状态。

你应该做的是在你的棋盘类中添加一个b1方法,它会返回另一个Board实例(使用b2并复制值)并通过以下方式更改你的代码:

public Board copy()