Я использую Inconsolata с UltraEdit в Windows. С TextMate (на Mac) я предпочитаю Монако (это - стандартный шрифт).
Из вашего примера видно, что вы не просите исключить перекрытие (например, 1 и 2 имеют общий верхний левый сегмент), поэтому, возможно, это будет соответствовать вашим потребностям:
Разделите пространство на прямоугольники на основе углов, обозначенных занятыми пространствами.
Сформируйте «базовые прямоугольники», протянув линейные сегменты от этих углов до краев всего пространства.
Используя любой систематический порядок (например, сверху- снизу, слева направо):
3.1. Выберите основной прямоугольник и расширьте его, насколько это возможно, с другими основными прямоугольниками, имеющими общую сторону.
3.2. Сформируйте набор всех (уникальных) таких расширенных прямоугольников.
Обратите внимание, что этот поиск / построение основывается на «базовых прямоугольниках» из шага 2, а не по пунктам во всем пространстве, поэтому производительность должна быть очень высокой. лучше.
(обратите внимание, что 3.1 - это тот же алгоритм, только с инвертированием свободного / заблокированного и с другими координатами)
Простите за ввод кодов:
for(int y = 0; y < rows; y++){
for(int x = 0; x < columns; x++){
// (x, y) would be the current space
if(checkEmptySpace(x,y)){
// empty space found
}
}
}
Это самый простой и прямой способ сделать это. но плохой момент в том, что он должен перебирать все пространство, что может вызвать неэффективность.
Импровизированный:
char mark = 'A';
for(i from 0 to rows)
colstart = 0;
while(colstart = next empty col in ith row)
width = 0;
for(j from colstart to columns)
{
if(empty)
width++;
else
break;
}
if(width == 0)
continue
for(n from colstart to colstart + width)
for(m from i to rows)
if(!empty)
break;
if(m != i)
set the rectangle from i, colstart to m - 1, colstart + width
with mark char and increment mark;
обновление: код java.
public class Program
{
public static char occuppied;
public static char vacant;
public static char mark;
public static void main(String[] args)
{
int rows = 7;
int cols = 11;
mark = 'A';
occuppied = '#';
vacant = '-';
char[][] matrix = new char[rows][cols];
setRect(matrix, vacant, 0, 0, rows, cols);
setRect(matrix, occuppied, 3, 3, 2, 2);
setRect(matrix, occuppied, 5, 5, 2, 6);
print(matrix);
for(int i = 0; i < rows; i++)
{
int colstart = 0;
while((colstart = nextEmptyCol(matrix[i], colstart)) != -1)
{
int width = 0;
for(int j = colstart; j < cols; j++)
{
if(matrix[i][j] == vacant)
width++;
else
break;
}
if(width == 0)
continue;
int height = 1;
outer:
for(; height + i < rows; height++)
for(int n = 0; n < width; n++)
{
if(matrix[i + height][colstart + n] == occuppied)
break outer;
}
System.out.println("width = " + width + ", height = " + height);
setRect(matrix, mark, i, colstart, height, width);
print(matrix);
mark++;
}
}
}
public static void setRect(char[][] matrix, char c, int startrow, int startcol, int numrows, int numcols)
{
for(int i = 0; i < numrows; i++)
for(int j = 0; j < numcols; j++)
matrix[startrow + i][startcol + j] = c;
}
public static void print(char[][] matrix)
{
int rows = matrix.length;
int cols = matrix[0].length;
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
System.out.print(matrix[i][j] + " ");
System.out.println();
}
for(int i = 0; i < cols; i++)
System.out.print("==");
System.out.println();
}
public static int nextEmptyCol(char[] row, int start)
{
for(int i = start; i < row.length; i++)
if(row[i] == vacant)
return i;
return -1;
}
}
Я думаю, что вы можете реализовать подход Монте-Карло .
С уважением.