我正在努力想出一个简洁的算法来找到矩形板的所有对角线。
这是Board
对象的简化版本。标有 NOT RIGHT YET 的位是我确定我错的地方。目前,它应该正确列出一个高于宽度的矩形的所有对角线,并正确找到正方形的两个对角线。对于宽度大于高的人来说,这是错误的。
现在是代码 - 看看没有为4 X 2板构建对角线。
/**
* The board.
*/
static class Board {
/**
* Top left corner is 0,0. Access is [y][x].
*/
final Square[][] board;
// The board as columns.
final List<List<Square>> columns;
// The dagonals.
final List<List<Square>> diagonals;
// For sense checking.
final int width;
final int height;
// A clear square.
private static final char Clear = ' ';
public Board(int width, int height) {
this.width = width;
this.height = height;
board = new Square[height][];
for (int y = 0; y < height; y++) {
board[y] = new Square[width];
// Fill it.
for (int x = 0; x < width; x++) {
board[y][x] = new Square(x, y);
}
}
// Build my columns lists.
columns = new ArrayList<>();
for (int x = 0; x < width; x++) {
List<Square> column = new ArrayList<>();
for (int y = 0; y < height; y++) {
column.add(board[y][x]);
}
columns.add(column);
}
// And the diagonals - NOT RIGHT YET!
diagonals = new ArrayList<>();
for (int y = 0; y <= height - width; y++) {
List<Square> diagonal = new ArrayList<>();
// Left to right.
for (int x = 0; x < width; x++) {
diagonal.add(board[y + x][x]);
}
diagonals.add(diagonal);
// Right to left.
diagonal = new ArrayList<>();
for (int x = 0; x < width; x++) {
diagonal.add(board[y + x][width - 1 - x]);
}
diagonals.add(diagonal);
}
}
public Board(int size) {
this(size, size);
}
public Stream<List<Square>> asRows() {
// Map each row to a list.
return Arrays.stream(board).map(r -> Arrays.asList(r));
}
public Stream<List<Square>> asCols() {
// Walk the columns.
return columns.stream();
}
public Stream<List<Square>> asDiagonals() {
// Walk the diagonals.
return diagonals.stream();
}
public Square square(Place place) {
return board[place.y][place.x];
}
/**
* One square of the board.
*
* Remember that a Square is ON a board - i.e. it is a sub-object of a Board. Do not attempt to memoize Squares as they will hold a reference to their parent board.
*/
class Square {
// where it is on the board.
final Place place;
public Square(Place place) {
this.place = place;
}
public Square(int x, int y) {
this(new Place(x, y));
}
@Override
public String toString() {
return place.toString();
}
}
/**
* A place on the board.
*/
class Place {
final int x;
final int y;
public Place(int x, int y) {
// Sense check.
if (x < 0 || x >= width) {
throw new IllegalArgumentException("Off board: x = " + x);
}
if (y < 0 || y >= height) {
throw new IllegalArgumentException("Off board: x = " + x);
}
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "{" + x + "," + y + '}';
}
}
}
private void test(int width, int height) {
Board board = new Board(width, height);
System.out.println(width + " X " + height);
for (List<Board.Square> d : board.diagonals) {
System.out.println(d);
}
}
public void test() {
test(3, 3);
test(4, 2);
test(2, 4);
}
public static void main(String args[]) {
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
输出
3 X 3
[{0,0}, {1,1}, {2,2}]
[{2,0}, {1,1}, {0,2}]
4 X 2
2 X 4
[{0,0}, {1,1}]
[{1,0}, {0,1}]
[{0,1}, {1,2}]
[{1,1}, {0,2}]
[{0,2}, {1,3}]
[{1,2}, {0,3}]