忽略在2D阵列中包裹非对角线单元格

时间:2014-03-09 17:29:31

标签: java algorithm multidimensional-array wrapping

简介

我创建了一个类,它生成一个充当网格的二维整数数组。此网格包含一个名为getNeighbors()的方法。这个方法应该得到所有八个周围的邻居,它确实如此,但我需要删除溢出的邻居。想象一下国际象棋中的女王。她可以向各个方向移动:垂直,水平和对角线。

Queen has 8 moves:      Queen has 6 moves
+---+---+---+           +---+---+---+
| y | y | y |           | Q | y | y |
+---+---+---+           +---+---+---+
| y | Q | y |           | y | y | n |
+---+---+---+           +---+---+---+
| y | y | y |           | y | n | y |
+---+---+---+           +---+---+---+

3x3网格布局:

+---+---+---+
| 0 | 1 | 2 |
+---+---+---+
| 3 | 4 | 5 |
+---+---+---+
| 6 | 7 | 8 |
+---+---+---+

现在,我想知道我是否可以检测一个细胞是否与物理上相邻而不是理论上(溢出包裹)。有没有一个解决方案不影响搜索neigbors的性能,特别是在更大的网格上?

实际结果:

Neighbors for (0): [8, 6, 7, 2, 1, 5, 3, 4]  
Neighbors for (1): [6, 7, 8, 0, 2, 3, 4, 5]  
Neighbors for (2): [7, 8, 6, 1, 0, 4, 5, 3]  
Neighbors for (3): [2, 0, 1, 5, 4, 8, 6, 7]  
Neighbors for (4): [0, 1, 2, 3, 5, 6, 7, 8]  
Neighbors for (5): [1, 2, 0, 4, 3, 7, 8, 6]  
Neighbors for (6): [5, 3, 4, 8, 7, 2, 0, 1]  
Neighbors for (7): [3, 4, 5, 6, 8, 0, 1, 2]  
Neighbors for (8): [4, 5, 3, 7, 6, 1, 2, 0]  

预期结果:

Neighbors for (0): [8, 6, -, 2, 1, -, 3, 4]  
Neighbors for (1): [-, 7, -, 0, 2, 3, 4, 5]  
Neighbors for (2): [-, 8, 6, 1, 0, 4, 5, -]  
Neighbors for (3): [-, 0, 1, 5, 4, -, 6, 7]  
Neighbors for (4): [0, 1, 2, 3, 5, 6, 7, 8]  
Neighbors for (5): [1, 2, -, 4, 3, 7, 8, -]  
Neighbors for (6): [-, 3, 4, 8, 7, 2, 0, -]  
Neighbors for (7): [3, 4, 5, 6, 8, -, 1, -]  
Neighbors for (8): [4, 5, -, 7, 6, -, 2, 0]

司机&支持类

驱动:

public class Calculate {
    public static void main(String[] args) {
        Board b = new Board(5);

        System.out.println(b);

        for (int i = 0; i < b.getCellCount(); i++) {
            System.out.println(b.getNeighborsAsString(i));
        }
    }
}

扩展抽象网格以提供业务逻辑:

public class Board extends AbstractGrid {
    public Board(int size) {
        super(size);
    }

    public int[] getNeighbors(int currRow, int currCol) {
        int prevCol = (currCol - 1 + size) % size;
        int nextCol = (currCol + 1) % size;
        int prevRow = (currRow - 1 + size) % size;
        int nextRow = (currRow + 1) % size;

        return new int[] {
            cells[prevRow][prevCol], // North-West
            cells[prevRow][currCol], // North
            cells[prevRow][nextCol], // North-East

            cells[currRow][prevCol], // West
            cells[currRow][nextCol], // East

            cells[nextRow][prevCol], // South-West
            cells[nextRow][currCol], // South
            cells[nextRow][nextCol] // South-East
        };
    }

    public String getNeighborsAsString(int index) {
        return getNeighborsAsString(index / size, index % size);
    }

    public String getNeighborsAsString(int row, int col) {
        StringBuffer buff = new StringBuffer();
        int[] neighbors = getNeighbors(row, col);
        int index = row * size + col;

        buff.append(String.format("Neighbors for (%s): [", frmtInt(index)));

        for (int i = 0; i < neighbors.length; i++) {
            buff.append(frmtInt(neighbors[i]));

            if (i < neighbors.length - 1) {
                buff.append(", ");
            }
        }

        return buff.append("]").toString();
    }
}

创建一个2D整数数组并处理打印:

public abstract class AbstractGrid {
    protected int[][] cells;
    protected int size;

    public static final String LF = System.getProperty("line.separator");

    private int base = 16;
    private int cellWidth;
    private String zeroPad;
    private String padding;
    private boolean showBorder = true;

    public AbstractGrid(int size) {
        if (size % 2 == 0 || (size < 3 && size > 25)) {
            throw new IllegalArgumentException(
                    "Board size must be an odd number between 3 and 25 (inclusive)");
        }

        this.size = size;
        this.cellWidth = Integer.toString(size * size - 1, base).length();
        this.zeroPad = String.format(String.format("%%0%dd", cellWidth), 0);
        this.padding = String.format("%%%ds", cellWidth);
        this.cells = new int[size][size];

        for (int row = 0; row < size; row++) {
            for (int col = 0; col < size; col++) {
                cells[row][col] = row * size + col;
            }
        }
    }

    public String frmtInt(int value) {
        StringBuffer buff = new StringBuffer(zeroPad).append(Integer.toString(
                value, base).toUpperCase());
        return buff.substring(buff.length() - zeroPad.length());
    }

    public String frmtStr(String value) {
        return String.format(padding, value);
    }

    private StringBuffer generateHorizontalLine(StringBuffer buff) {
        if (showBorder) {
            buff.append('+');
        }

        for (int col = 0; col < size; col++) {
            for (int i = 0; i <= cellWidth + 1; i++) {
                buff.append('-');
            }

            if (col < size - 1) {
                buff.append('+');
            }
        }

        if (showBorder) {
            buff.append('+');
        }

        return buff.append(LF);
    }

    private StringBuffer generateHorizontalRow(StringBuffer buff, int row) {
        if (showBorder) {
            buff.append('|');
        }

        buff.append(" ");

        for (int col = 0; col < size; col++) {
            buff.append(frmtInt(cells[row][col]));

            if (showBorder || col < size - 1) {
                buff.append(" | ");
            }
        }

        buff.append(LF);

        if (row < size - 1) {
            return generateHorizontalLine(buff);
        }

        return buff;
    }

    public int getCell(int index) {
        return cells[index / size][index % size];
    }

    public int getCell(int row, int col) {
        return cells[row][col];
    }

    public int getCellCount() {
        return size * size;
    }

    public int getSize() {
        return size;
    }

    @Override
    public String toString() {
        StringBuffer buff = new StringBuffer();
        if (cells != null) {
            if (showBorder) {
                generateHorizontalLine(buff);
            }

            for (int row = 0; row < size; row++) {
                generateHorizontalRow(buff, row);
            }

            if (showBorder) {
                generateHorizontalLine(buff);
            }
        }

        return buff.toString();
    }
}

0 个答案:

没有答案