使用二维数组解决八皇后问题:IndexOutOfBounds错误。

3
我的一项作业要求使用二维数组解决八皇后问题。在我的“isUnderAttack”方法中,我不断收到索引越界错误:8,出现在以下位置:
if (board[row][j] == QUEEN)

在我的 "placeQueen" 方法中:

if (isUnderAttack(row, column)) {

并且

queenPlaced = placeQueens(column+1);

我可能哪里做错了?我会在这篇文章中添加更多标签,但我是一个新用户,无法创建“新标签”。抱歉!

这是我创建的内容:

public class Queens {
      // squares per row or column
      public static final int BOARD_SIZE = 8; 

      // used to indicate an empty square
      public static final int EMPTY = 0; 

      // used to indicate square contains a queen
      public static final int QUEEN = 1; 

      private int board[][]; // chess board
      public Queens() {
      // -------------------------------------------------
      // Constructor: Creates an empty square board.
      // -------------------------------------------------
        board = new int[BOARD_SIZE][BOARD_SIZE];
      }  // end constructor         

      public void clearBoard() {
      // -------------------------------------------------
      // Clears the board.
      // Precondition: None.
      // Postcondition: Sets all squares to EMPTY.
      // -------------------------------------------------
        //loops through rows
          for (int i = 0; i < BOARD_SIZE; i++){
              //loops through columns
            for (int j = 0; j <BOARD_SIZE; j++){
                board[i][j] = EMPTY;
            }
        }
      }  // end clearBoard

      public void displayBoard() {
      // -------------------------------------------------
      // Displays the board.
      // Precondition: None.
      // Postcondition: Board is written to standard 
      // output; zero is an EMPTY square, one is a square 
      // containing a queen (QUEEN).
      // -------------------------------------------------

          for (int i = 0; i < BOARD_SIZE; i++){
              System.out.println("");

            for (int j = 0; j <BOARD_SIZE; j++){
                System.out.print(board [i][j] + " ");
            }
          }
      } // end displayBoard

      public boolean placeQueens(int column) {
      // -------------------------------------------------
      // Places queens in columns of the board beginning 
      // at the column specified.
      // Precondition: Queens are placed correctly in 
      // columns 1 through column-1.
      // Postcondition: If a solution is found, each 
      // column of the board contains one queen and method 
      // returns true; otherwise, returns false (no 
      // solution exists for a queen anywhere in column 
      // specified).
      // -------------------------------------------------
        if (column > BOARD_SIZE) {
          return true;  // base case
        } 
        else {
          boolean queenPlaced = false;
          int row = 1;  // number of square in column

          while ( !queenPlaced && (row <= BOARD_SIZE) )  {
            // if square can be attacked
            if (isUnderAttack(row, column)) {
              ++row;  // consider next square in column
            } // end if
            else { // place queen and consider next column
              setQueen(row, column);
              queenPlaced = placeQueens(column+1);
              // if no queen is possible in next column,
              if (!queenPlaced) {
                // backtrack: remove queen placed earlier
                // and try next square in column
                removeQueen(row, column);
                ++row;
              } // end if
            } // end if
          } // end while
          return queenPlaced;
        } // end if
      } // end placeQueens

      private void setQueen(int row, int column) {
      // --------------------------------------------------
      // Sets a queen at square indicated by row and 
      // column.
      // Precondition: None.
      // Postcondition: Sets the square on the board in a 
      // given row and column to QUEEN.
      // --------------------------------------------------
        board [row][column] = QUEEN;
      }  // end setQueen

      private void removeQueen(int row, int column) {
      // --------------------------------------------------
      // Removes a queen at square indicated by row and
      // column.
      // Precondition: None.
      // Postcondition: Sets the square on the board in a 
      // given row and column to EMPTY.
      // --------------------------------------------------
        board [row][column] = EMPTY;
      }  // end removeQueen

      private boolean isUnderAttack(int row, int column) {
      // --------------------------------------------------
      // Determines whether the square on the board at a 
      // given row and column is under attack by any queens 
      // in the columns 1 through column-1.
      // Precondition: Each column between 1 and column-1 
      // has a queen placed in a square at a specific row. 
      // None of these queens can be attacked by any other
      // queen.
      // Postcondition: If the designated square is under 
      // attack, returns true; otherwise, returns false.
      // --------------------------------------------------
          //i = rows and j = columns
          //----------------------------------------
          //
          // Checks before and after square
          //
          //----------------------------------------

          //looks behind for queens
          for (int j = 0; j < column; j++){
            if (board[row][j] == QUEEN)
                return true;
        }
        //looks in front for queens
        for (int j =column+1; j < BOARD_SIZE; j++){
            if(board[row][j] == QUEEN)
                return true;
        }
        //-----------------------------------------------------------------
        //
        // Checks diagonally from square
        //
        //-----------------------------------------------------------------
        for (int i = 1+row, j = 1+column; i < BOARD_SIZE && j < BOARD_SIZE; i++, j++){
            if (board[i][j] == QUEEN)
                return true;
        }
        for (int i= 1-row, j = 1-column; i >= 0 && j >=0; i--, j--){
            if (board[i][j] == QUEEN)
                return true;
        }
        for (int i= 1+row, j = 1-column; i < BOARD_SIZE && j >= 0; i++, j--){
            if (board[i][j] == QUEEN)
                return true;
        }
        for (int i= 1-row, j = 1+column; i >= 0 && j < BOARD_SIZE; i--, j++){
            if (board[i][j] == QUEEN)
                return true;
        }
        return false;
      }  // end isUnderAttack

      private int index(int number) {
      // --------------------------------------------------
      // Returns the array index that corresponds to
      // a row or column number.
      // Precondition: 1 <= number <= BOARD_SIZE.
      // Postcondition: Returns adjusted index value.
      // --------------------------------------------------
        return number -1;
      }  // end index
    } // end Queens

1
使用调试器逐步执行代码。注意在isUnderAttack:8处rowcolumnij的值。 - Christian Mann
1
顺便提一句,如果这是Java(看起来很像),请使用Javadocs而不是单行注释 :) - irrelephant
从未真正使用过Javadocs。我会研究一下。谢谢! - Bell
2个回答

3

将此行更改:

while ( !queenPlaced && (row <= BOARD_SIZE) ) {

更改为:

while ( !queenPlaced && (row < BOARD_SIZE) ) {

因为BOARD_SIZE被定义为8,这是数组大小(8x8),当isUnderAttack()函数试图访问board[8][j]时,它会超出边界。 它只能访问0-7行。

另外,您可能需要更改刚刚在上面的一行(int row = 1;),将行设置为0而不是1(假设您想从第一行开始)。


我尝试了你的第一个建议,没有出现任何错误。然而仍然存在问题。虽然没有出现错误,但是我的棋盘现在没有显示任何皇后。我尝试将int row更改为0,但是出现了错误。这是否意味着我编写的"isUnderAttack"方法有误? - Bell
1
很可能。我看到你在isUnderAttack()中对角线检查存在逻辑错误。即具有“int i = 1-行”或“1-列”的for循环。你应该将它们改为“行-1”和“列-1”,因为它们最初(或在最多2次迭代后)进入负范围,因此i或j变为-1,此时for循环终止。 - Amy

0

由于您将皇后从左列放置到右列,因此右侧不应该有任何要检查的皇后。因此,您可以消除所有右侧的检查。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接