[英]N-Queens using a stack, cannot find the bug
我试图完成我的家庭作业项目,并寻求帮助以查找错误。 我正在使用回溯算法来查找N皇后问题的所有解决方案。 我主要关心的是我的冲突方法,该方法位于堆栈类中。 其目的是检测所传递的皇后对象(冲突方法的参数1)是否与板上的其他皇后在同一行,同一列或对角线中。 传递给冲突方法的Queen对象存储在Queen类内部,并在Point类的实例的帮助下记录其位置。 我的代码在我创建的Queen类中使用了两种方法,即public int getRow()和public int getColumn()。 两者都返回一个int。 第二个参数是一个名为board的二维数组(或数组数组)。 在此数组中,已经在板上的皇后用布尔值true表示。 布尔值false表示板上的空白方块。
Solution.n是对另一个类中的静态int变量的引用。 其值表示板的边缘。 示例...对于8皇后问题,我们创建了一个大小为8的2d数组。Solution.n递减1以等于2d数组的最后一个索引。
这是代码:
public boolean conflict(Queen x, boolean [][] board) //conflict method
{
if(checkColumn(x, board) == false)
return true; //conflict
else if(checkRow(x, board) == false)
return true; //conflict
else if(checkDiagonal(x, board) == false )
return true; //conflict
else
return false; //no conflict on board
}
private boolean checkColumn(Queen x, boolean [][] board)//returns true when column is safe
{
int col = x.getColumn();
for(int row = 0; row <= Solution.n; row++)
{
if(board[row][col] == true) //queen is in this column
{
return false;
}
}
return true;
}
private boolean checkRow(Queen x, boolean [][] board) //returns true when row is safe
{
int row = x.getRow();
for(int col = 0; col <= Solution.n; col++)
{
if(board[row][col] == true) //queen is in this row
{
return false;
}
}
return true;
}
private boolean checkDiagonal(Queen location, boolean [][] board) //returns true when diagonal is safe
{
int row, col;
row = location.getRow() - 1;
col = location.getColumn() - 1;
while(row >=0 && col >= 0) //iterate down-left
{
if(board[row][col] == true) //queen found?
{
return false;
}
row--;
col--;
}
row = location.getRow() - 1;
col = location.getColumn() + 1;
while(row != -1 && col <= Solution.n) //iterate down-right
{
if(board[row][col] == true) //queen found?
{
return false;
}
row--;
col++;
}
row = location.getRow() + 1;
col = location.getColumn() + 1;
while(row <= Solution.n && col <= Solution.n) //iterate up-right
{
if(board[row][col] == true) //queen found?
{
return false;
}
row++;
col++;
}
row = location.getRow() +1;
col = location.getColumn()-1;
while(row <= Solution.n && col != -1) //iterate up-left
{
if(board[row][col] == true) //queen found?
{
return false;
}
row++;
col--;
}
return true;
}
我确信这段代码包含一个错误,但是如果我错了,那么我为您的浪费而致歉:P
您的帮助将不胜感激。 谢谢! :d
您那里有几个小错误-例如,您的循环从0
到Solution.n
(含),而循环则应到达Solution.n-1
。 但是,大多数错误可以通过选择更合适的数据结构来消除。
想想看:您不需要一个完整的N
x N
板来决定女王的位置:
boolean[N]
数组才能知道采用了哪些行。 boolean[2N-1]
数组来知道采用哪个上升对角线。 每个下降对角线都有一个皇后,因此您需要一个boolean[2N-1]
数组来知道采用哪个下降对角线。
boolean []列=新的boolean [N]; boolean []升序=新的boolean [2 * N-1]; boolean []降序=新的boolean [2 * N-1];
至此,您已经拥有了所需要的一切:不需要正方形的boolean[N][N]
数组,您需要三个boolean
线性数组。 这也使您可以更快地进行检查:
int c = x.getColumn();
int r = x.getRow();
boolean conflict = columns[c]
|| ascending[r+c]
|| descending[N-r+c];
就是这样-不需要循环! 现在,您可以使用这三个数组而不是方形板来编码回溯算法。
这个答案不会解决您的问题,因为我不相信您的错误是在您粘贴的代码中,但是这是您的代码,写得更接近我的写法:
// returns true when column is safe
private boolean checkColumn(Queen x, boolean [][] board)
{
int col = x.getColumn();
for(int row = 0; row <= Solution.n; row++)
{
if(board[row][col]){ return false; }
}
return true;
}
// returns true when row is safe
private boolean checkRow(Queen x, boolean [][] board)
{
int row = x.getRow();
for(int col = 0; col <= Solution.n; col++)
{
if(board[row][col]){ return false; }
}
return true;
}
// returns true if the position is valid given the board size
// (as defined by Solution)
private boolean validPosition(int row, int col)
{
if(0 > row || row > Solution.n){ return false; }
if(0 > col || col > Solution.n){ return false; }
return true;
}
// returns true when diagonal is safe
private boolean checkDiagonal(Queen x, boolean [][] board)
{
int row, col;
// Down Left
row = x.getRow(); // "Start" on current position
col = x.getColumn();
while(true)
{
row--; col--; // Take a step in the direction
if(!validPosition(row, col)){ break; } // Stop if we've left the board
if(board[row][col]){ return false; } // Check whether it's occupied
}
// Down Right
row = x.getRow();
col = x.getColumn();
while(true)
{
row--; col++;
if(!validPosition(row, col)){ break; }
if(board[row][col]){ return false; }
}
// Up Right
row = x.getRow();
col = x.getColumn();
while(true)
{
row++; col++;
if(!validPosition(row, col)){ break; }
if(board[row][col]){ return false; }
}
// Up Left
row = x.getRow();
col = x.getColumn();
while(true)
{
row++; col--;
if(!validPosition(row, col)){ break; }
if(board[row][col]){ return false; }
}
return true;
}
public boolean conflict(Queen x, boolean [][] board) //conflict method
{
if ( checkColumn(x, board) == false){ return true; }
else if( checkRow(x, board) == false){ return true; }
else if(checkDiagonal(x, board) == false){ return true; }
else { return false; }
}
}
它简化了很多逻辑,添加了一个辅助函数validPosition()
,并清理了一些测试和循环。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.