簡體   English   中英

Java - 如何避免訪問二維數組中的無效位置?

[英]Java - How to avoid accessing an invalid position in a 2d array?

我正在研究 Knight's Tour 問題,並且正在為它制定遞歸解決方案。 https://www.chess.com/terms/knights-tour-chess#:~:text=The%20knight's%20tour%20is%20a,same%20square%20more%20than%20once

我有一個矩陣 [8][8] 和一個名為knightMove(int currentRow, int currentColumn); 此方法應該騎士可以從當前位置進行的所有可能的移動添加到一個數組中。 如果可能移​​動的位置值等於 0,則knightMove(newRow, newColumn)將從新位置再次調用;

如果它找到死角,那么它將嘗試在上一次調用中數組中的下一個可能的移動,如果它用完之前的數組位置,那么它將嘗試在此之前調用的數組中的下一個位置,依此類推。 該程序只有在找到問題的正確解決方案時才會結束。

現在是我的問題,我想避免使用這么多的“如果”來檢查騎士的舉動是否出局。

    ArrayList <int[]> moves = new ArrayList<int[]>();
    int[] arr = new int[2];
    int max=8;
    if (currentColumn-2 > 0){
        
        if(currentRow - 1 > 0){
            arr[0] = currentColumn-2;
            arr[1] = currentRow-1;  
            moves.add(arr);
        } 
        
        if(currentRow+1 < max){
            arr[0] = currentColumn-2;
            arr[1] = currentRow+1;
            moves.add(arr);
        }
    } 
   if (currentRow-2 > 0){
        
        if(currentColumn-1 > 0){                
            arr[0] = currentColumn-1;  
            arr[1] = currentRow-2;
            moves.add(arr);  
        } 
        
        if(currentColumn+1 < max){
            arr[0] = currentColumn+1;
            arr[1] = currentRow-2;
            moves.add(arr);
        }
    } 
    if (currentColumn+2 > 0){
        
        if(currentRow-1 > 0){
            arr[0] = currentColumn+2;
            arr[1] = currentRow-1;  
            moves.add(arr);
        } 
        
        if(currentRow+1 < max){
            arr[0] = currentColumn+2;
            arr[1] = currentRow+1;
            moves.add(arr);
        }
    } 
    if (currentRow+2 > 0){
       
        if(currentColumn-1 > 0){
            arr[0] = currentColumn-1;  
            arr[1] = currentRow+2;
            moves.add(arr);
        } 
       
        if(currentRow+1 < max){
            arr[0] = currentColumn+2;
            arr[1] = currentRow+1;
            moves.add(arr);
        }
    } 

     for (int[] c : moves){
     // recursive logic...
     }

我對無效位置不感興趣,如果編譯器無法訪問這樣的無效位置,所以不要對它們做任何事情,不要破壞我的代碼,專注於那些真正有效的位置。 我想做類似下面的事情,只添加數組中有效位置的值(utopic 解決方案):

int[] temp = {
            table[currentRow-2][currentColumn-1], 
            table[currentRow-2][currentColumn+1], 
            table[currentRow+1][currentColumn-2], 
            table[currentRow-1][currentColumn-2],  
            table[currentRow+2][currentColumn-1], 
            table[currentRow+2][currentColumn+1], 
            table[currentRow-1][currentColumn+2], 
            table[currentRow+1][currentColumn+2]  
        };

我想幫助找出一種更好的方法來避免訪問矩陣中的無效位置。

這是我多次測試運行之一的結果。

Origin row: 3, column: 4
    Move to row: 1, column: 5
    Move to row: 1, column: 3
    Move to row: 2, column: 6
    Move to row: 2, column: 2
    Move to row: 4, column: 6
    Move to row: 4, column: 2
    Move to row: 5, column: 5
    Move to row: 5, column: 3

Origin row: 1, column: 1
    Move to row: 0, column: 3
    Move to row: 2, column: 3
    Move to row: 3, column: 2
    Move to row: 3, column: 0

Origin row: 7, column: 7
    Move to row: 5, column: 8
    Move to row: 5, column: 6
    Move to row: 6, column: 5
    Move to row: 8, column: 5

Origin row: 1, column: 7
    Move to row: 0, column: 5
    Move to row: 2, column: 5
    Move to row: 3, column: 8
    Move to row: 3, column: 6

Origin row: 7, column: 1
    Move to row: 5, column: 2
    Move to row: 5, column: 0
    Move to row: 6, column: 3
    Move to row: 8, column: 3

我做的第一件事是創建一個Coordinate類。 這允許我將索引越界測試放在Coordinate類中的一個位置。

knightMove方法計算出有多少移動是有效的,創建一個 Coordinates 數組,並返回有效的移動坐標。

這是完整的、可運行的代碼。

public class MoveKnight {

    public static void main(String[] args) {
        MoveKnight mk = new MoveKnight();
        displayOutput(mk, 3, 4);
        displayOutput(mk, 1, 1);
        displayOutput(mk, 7, 7);
        displayOutput(mk, 1, 7);
        displayOutput(mk, 7, 1);
    }

    private static void displayOutput(MoveKnight mk, int row, int column) {
        System.out.println("Origin row: " + row + ", column: " + column);
        Coordinate[] output = mk.knightMove(row, column);
        for (int index = 0; index < output.length; index++) {
            System.out.println("    Move to row: " + output[index].getRow() + 
                    ", column: " + output[index].getColumn());
        }
        System.out.println();
    }

    public Coordinate[] knightMove(int currentRow, int currentColumn) {
        Coordinate[] difference = { new Coordinate(-2, 1), new Coordinate(-2, -1), 
                new Coordinate(-1, 2), new Coordinate(-1, -2), new Coordinate(1, 2), 
                new Coordinate(1, -2), new Coordinate(2, 1), new Coordinate(2, -1) };

        int count = 0;
        for (int index = 0; index < difference.length; index++) {
            Coordinate destination = new Coordinate(currentRow, currentColumn);
            destination.incrementCoordinate(difference[index]);
            if (destination.isValid()) {
                count++;
            }
        }

        Coordinate[] output = new Coordinate[count];
        count = 0;
        for (int index = 0; index < difference.length; index++) {
            Coordinate destination = new Coordinate(currentRow, currentColumn);
            destination.incrementCoordinate(difference[index]);
            if (destination.isValid()) {
                output[count++] = destination;
            }
        }

        return output;
    }

    public class Coordinate {

        private int column, row;

        public Coordinate(int row, int column) {
            setRowColumn(row, column);
        }

        public int getColumn() {
            return column;
        }

        public int getRow() {
            return row;
        }

        public void incrementCoordinate(Coordinate increment) {
            this.row += increment.getRow();
            this.column += increment.getColumn();
        }

        public void setRowColumn(int row, int column) {
            this.row = row;
            this.column = column;
        }

        public boolean isValid() {
            return row >= 0 && row < 8 && column >= 0 && column < 8;
        }

    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM