Java 基于递归的数组问题
我正试图完成一个高中编程项目,但有一个bug阻止我完成。该计划/项目旨在解决“非攻击皇后”难题,即在棋盘上找到皇后的所有位置,其中同一行、列或对角线中没有两个皇后。我们需要使用递归来解决这个问题 现在,我遇到的问题是双重的。首先,每次我在特定索引处向Java 基于递归的数组问题,java,arrays,recursion,scope,Java,Arrays,Recursion,Scope,我正试图完成一个高中编程项目,但有一个bug阻止我完成。该计划/项目旨在解决“非攻击皇后”难题,即在棋盘上找到皇后的所有位置,其中同一行、列或对角线中没有两个皇后。我们需要使用递归来解决这个问题 现在,我遇到的问题是双重的。首先,每次我在特定索引处向solvedChessBoards数组添加解决方案时,数组的所有元素都会更新到这个最新的解决方案,尽管我在赋值中只使用了一个索引。这意味着,一旦我解决了所有可能的解决方案,我的数组只包含一个解决方案(最后添加的一个),但只包含几次 第二个问题是,一旦
solvedChessBoards
数组添加解决方案时,数组的所有元素都会更新到这个最新的解决方案,尽管我在赋值中只使用了一个索引。这意味着,一旦我解决了所有可能的解决方案,我的数组只包含一个解决方案(最后添加的一个),但只包含几次
第二个问题是,一旦solveBoard()
方法完成执行,solvedChessBoards
数组将丢失其所有值,尽管它是一个类变量。当我尝试打印所有解决方案时,这是有问题的,因为数组不再包含任何信息
我认为这个问题源于对递归以及数据如何存储在java中的误解。我希望有人不仅能帮我解决问题,还能“教”我做错了什么,这样我将来就可以避免类似的问题
请注意,虽然Board
类中的其他方法很重要,但我不认为该错误源自solveBoard
方法之外的任何方法。出于这个原因,我认为唯一值得尊敬的代码就在这个方法中
这是我的板
课程的代码:
/**
* Class that creates a board of given equal dimensions. Also has methods and variables pertaining to
* Queen chesspieces that can be placed on the board.
*
* @Andrew Smith
* @2/14/16
*/
public class Board
{
private int solvedBoardCount;
private final int QUEEN = 1, EMPTY = 0;
private int expectedSolutions;
private int[][] chessBoard;
private int[][][] solvedChessBoards;
//---------------------------------------------------------------------------------------------------------------------------------------------
// Creates a chess Board object with given dimensions. Each Board is square, with equal sides.
//---------------------------------------------------------------------------------------------------------------------------------------------
public Board (int dimension, int solutions) {
chessBoard = new int[dimension][dimension];
expectedSolutions = solutions;
solvedChessBoards = new int[expectedSolutions][dimension][dimension];
solveBoard(0, chessBoard);
}
//---------------------------------------------------------------------------------------------------------------------------------------------
// Creates the default chess Board object with dimensions of 4 on each side.
//---------------------------------------------------------------------------------------------------------------------------------------------
public Board () {
chessBoard = new int[4][4];
solvedChessBoards = new int[1][4][4];
solveBoard(0, chessBoard);
}
//---------------------------------------------------------------------------------------------------------------------------------------------
// This method does two things.
// First, it solves the given chess board under the rules of the "Non-Attacking Queens" puzzle. It does this recursively, iterating through
// all possible combinations of queen placement.
//
// Secondly, the method solves for every possible solution to the puzzle, and cataloges these solution 'boards' in the variable
// solvedChessBoards, a three dimensional array of 2 dimensional boards.
//---------------------------------------------------------------------------------------------------------------------------------------------
private void solveBoard(int row, int[][] tempBoard) {
for (int column = 0; column < tempBoard.length; column++) { //Goes across the columns of a given row
if (indexIsSafe(row, column)) { //Checks to see if the queen placement is valid
tempBoard[row][column] = QUEEN; //Sets placevalue of 1
if (row < tempBoard.length - 1) { //Unless the board has been solved
solveBoard(row+1, tempBoard);
deleteLastPosition(row);
}else{
solvedChessBoards[solvedBoardCount] = tempBoard; //Adds solved chessboard to the array
solvedBoardCount++;
deleteLastPosition(row);
}
}
}
}
//---------------------------------------------------------------------------------------------------------------------------------------------
// Takes a current row and column and tests to see if it is a viable spot for a queen.
// This would mean no queens above or in a diagonal path.
//---------------------------------------------------------------------------------------------------------------------------------------------
private boolean indexIsSafe(int currentRow, int currentColumn) { //Tests the current index; Returns True if a queen can be placed
int diagonal = 1; //Used to add/subtract in order to line up the diagonals of the chess board
for (int testRow = currentRow - 1; testRow >= 0; testRow--) {
if (chessBoard[testRow][currentColumn] == 1) { //Queen directly ABOVE
return false;
}
//First checks to make sure there is an index to the left
if (currentColumn - diagonal >= 0 && chessBoard[testRow][currentColumn - diagonal] == 1) { //Queen on LEFT DIAGONAL
return false;
}
//First checks to make sure there is an index to the right
if (currentColumn + diagonal < chessBoard.length && chessBoard[testRow][currentColumn + diagonal] == 1) { //Queen on RIGHT DIAGONAL
return false;
}
diagonal += 1; //Adjusts for the increasing distance of diagonals
}
return true; //A queen can be placed at the current index
}
//---------------------------------------------------------------------------------------------------------------------------------------------
// Deletes the last position (1 row above) in the given board. This is used to allow the program to progress along the columns without
// containing past queen placements.
//---------------------------------------------------------------------------------------------------------------------------------------------
private void deleteLastPosition (int currentRow) {
for (int column = 0; column < chessBoard.length; column++) { //Finds the queen in the row above the current row
if (chessBoard[currentRow][column] == 1) {
chessBoard[currentRow][column] = EMPTY;
}
}
}
//---------------------------------------------------------------------------------------------------------------------------------------------
// Prints the chess Board by returning a formatted string.
// Empty spaces are represented by 0s, and queens by 1's.
//---------------------------------------------------------------------------------------------------------------------------------------------
public String toString () {
String result = "";
for (int[][] solvedBoard: solvedChessBoards) {
for (int row = 0; row < solvedBoard.length; row++) {
for (int column = 0; column < solvedBoard.length; column++) {
result += solvedBoard[row][column];
}
result += "\n";
}
result += "\n--------------------------------------------- \n";
}
return result;
}
}
对于那些愿意帮助的人,提前非常感谢。这行:
solvedChessBoards[solvedBoardCount]=tempBoard
不复制由tempBoard
引用的数组-您正在solvedChessBoards
数组中存储对该数组的新引用,然后通过tempBoard
引用继续修改它。存储数组时,您需要实际复制该数组。我对Java非常生疏,所以我不能告诉你如何复制2d数组,但这至少对谷歌来说是个问题。还有一个小风格点:在构造函数中工作通常是不受欢迎的。我会单独打电话给solveBoard。谢谢你的引导。对于“构造函数中的工作”,我最初没有在其中调用该方法,但我认为数据丢失可能与驱动程序中的方法调用有关,而不是与类本身有关。这没有多大意义,但我正在尝试我能想到的一切。你完全正确,复制别名是我遇到的两个问题的根源。非常感谢你
/**
* Solves the Non-Attacking Queens Problem. In order to solve this riddle, a set of Queens must be placed
* on a blank chess board in a way that no queen is in the same column, row, or diagonal.
*
* @Andrew Smith
* @1/3/16
*/
public class QueensDriver
{
public static void main (String[] args) {
Board chessBoard = new Board(8,92);
System.out.print (chessBoard);
}
}