很难解释我想要的东西。假设我有一个0和1的矩阵
000000
000000
001100
000000
000000
我想从某一组开始(这是在开头给出的,然后我想向外走。
<00> 000000 ,,,,,,, 000000差异并不重要,只要我会向外通过所有事情。
我想这样做的原因是,这个1和0的矩阵对应于某个2D函数的矩阵,我想检查该函数中的点向外。我想
答案 0 :(得分:1)
如果我正确理解了这个问题,基本上你想要的是在矩阵中找到一组1并反转1s及其所有周围的组。这实际上是一个图像处理问题,所以我的解释也是如此。旁注:术语“多边形”&#39;这里用于矩阵中的1组。做出一些假设:多边形总是被填充。多边形不包含直接位于矩阵外边界的任何点(例如:点(0,2)永远不是多边形的一部分)。解决方案很容易找到:
步骤1:搜索任意1,它是矩阵中1s所代表的多边形外边界的一部分。通过从左上角开始,它保证返回的协调将属于多边形左侧,上侧或角落的1。
point searchArb1(int[][] matrix)
list search
search.add(point(0 , 0))
while NOT search.isEmpty()
point pt = search.remove(0)
//the point wasn't the searched one
if matrix[pt.x][pt.y] == 1
return pt
//continue search in 3 directions: down, right, and diagonally down/right
point tmp = pt.down()
if tmp.y < matrix.height
search.add(tmp)
tmp = pt.right()
if tmp.x < matrix.width
search.add(tmp)
tmp = pt.diagonal_r_d()
if tmp.x < matrix.width AND tmp.y < matrix.height
search.add(tmp)
return null
步骤2:既然我们在多边形的外边界有一个任意点,我们可以简单地通过搜索多边形的外边界来进行。由于上述假设,我们只需要在3个方向上搜索1(对角线总是由形成角落的3个点表示)。此方法将搜索顺时针方向绑定的多边形。
int UP = 0
int RIGHT = 1
int DOWN = 2
int LEFT = 3
list searchOuterBound(int[][] matrix , point arbp)
list result
point pt = arbp
point ptprev
//at each point one direction can't be available (determined using the previous found 1
int dir_unav = LEFT
do
result.add(pt)
//generate all possible candidates for the next point in the polygon bounds
map candidates
for int i in [UP , LEFT]
if i == dir_unav
continue
point try
switch i
case UP:
try = pt.up()
break
case DOWN:
try = pt.down()
break
case RIGHT:
try = pt.right()
break
case LEFT:
try = pt.left()
break
candidates.store(i , try)
ptprev = pt
for int i in [0 , 2]
//the directions can be interpreted as cycle of length 4
//always start search for the next 1 at the clockwise next direction
//relatively to the direction we come from
//eg.: dir_unav = LEFT -> start with UP
int dir = (dir_unav + i + 1) % 4
point try = candidates.get(dir)
if matrix[pt.x][pt.y] == 1
//found the first match
pt = try
//direction we come from is the exact opposite of dir
dir_unav = (dir + 2) % 4
break
//no matching candidate was found
if pt == ptprev
return result
while pt != arbp
//algorithm has reached the starting point again
return result
第3步:现在我们已经获得了多边形的表示。下一步:反转多边形周围的点。由于多边形本身将在稍后填充0,我们可以简单地用1s填充多边形中每个点的周围。由于生成矩阵状态的这一部分有两种选择,我将分为两种解决方案:
步骤3.1:使用1s填充多边形点的对角邻居的点
void fillNeighbours_Diagonal_Included(int[][] matrix , list polygon)
for point p in polygon
for int x in [-1 , 1]
for int y in [-1 , 1]
matrix[p.x + x][p.y + y] = 1
步骤3.1:不要填充多边形点的对角邻居的点
void fillNeighbours_Diagonal_Excluded(int[][] matrix , list polygon)
for point p in polygon
matrix[p.x - 1][p.y] = 1
matrix[p.x + 1][p.y] = 1
matrix[p.x][p.y - 1] = 1
matrix[p.x][p.y + 1] = 1
步骤4:最后,最后一步:将多边形中的所有1反转为0。注意:我懒得进一步优化这个,所以这个部分实现为暴力。
void invertPolygon(int[][] matrix , list polybounds)
//go through each line of the matrix
for int i in [0 , matrix.height]
sortedlist cut_x
//search for all intersections of the line with the polygon
for point p in polybounds
if p.y == i
cut_x.add(p.x)
//remove ranges of points to only keep lines
int at = 0
while at < cut_x.size()
if cut_x.get(at - 1) + 1 == cut_x.get(at)
AND cut_x.get(at) == cut_x.get(at + 1) - 1
cut_x.remove(at)
--at
//set all points in the line that are part of the polygon to 0
for int j in [0 , cut_x.size()[ step = 2
for int x in [cut_x.get(j) , cut_x.get(j + 1)]
matrix[x][i] = 0
我希望你理解这背后的基本理念。谢谢你的答案。