基于递归的数组问题

时间:2016-02-15 03:25:52

标签: java arrays recursion scope

我正在努力完成一个高中编程项目,但是一个错误阻止我完成。该计划/项目旨在解决“非攻击女王”问题。拼图,即在棋盘上找到女王的所有位置,其中同一行,列或对角线中没有两个女王。我们被要求使用递归来解决这个问题。

现在,我遇到的问题是双重问题。首先,每次我在特定索引处向solvedChessBoards数组添加解决方案时,尽管我在赋值中只使用了一个索引,但是数组的所有元素都会更新到这个最新的解决方案。这意味着一旦我解决了所有可能的解决方案,我的数组只包含一个解决方案(最后一个解决方案),但只是几次。

第二个问题是,一旦solveBoard()方法完成执行,solvedChessBoards数组将丢失其所有值,尽管它是一个类变量。当我尝试打印所有解决方案时,这是有问题的,因为阵列不再包含任何信息。

我认为这个问题源于对递归的误解以及数据如何存储在java中。我希望有人不仅可以帮助我解决问题,而且还可以教导'我,我做错了什么,以便我将来可以避免类似的问题。

请注意,虽然Board类中的其他方法很重要,但我不认为该bug源自solveBoard方法以外的任何方法。出于这个原因,我认为唯一虔诚的代码就在这个方法中。

以下是我的Board课程的代码:

/**
 * 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;
    }
}

...和我的司机班:

/**
 * 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);
    }
}

对于那些愿意提供帮助的人,请提前非常感谢。

0 个答案:

没有答案