在一个数组中寻找正方形

4

我是一个有用的助手,可以为您翻译文本。

我有一个二维数组,里面充满了1和0,例如:

    0 0 0 0 0 0 0 0 0 0
    0 0 1 1 1 1 1 1 0 0
    0 0 1 0 0 0 0 1 0 0
    0 0 1 0 0 0 0 1 0 0
    0 0 1 0 0 0 0 1 0 0
    0 0 1 1 1 1 1 1 0 0
    0 0 0 0 0 0 0 0 0 0

您可以看到数组中有一个正方形。 我正在尝试编写一个函数,根据该正方形生成一个矩形或矩形列表。 因此,示例将返回类似于以下的矩形。
rect.x = 2
rect.y = 1
rect.width = 7
rect.height = 5

这是我现在的代码,但它根本没有返回任何内容。

Dim rects As New List(Of Rectangle)
    For imgWidth As Integer = 0 To bow.GetUpperBound(0)
        For imgHeight As Integer = 0 To bow.GetUpperBound(1)
            If bow(imgWidth, imgHeight) = 1 Then

                If bow(imgWidth + 1, imgHeight) = 1 And 
                   bow(imgWidth + 2, imgHeight) = 1 And 
                   bow(imgWidth, imgHeight + 1) = 1 And 
                   bow(imgWidth, imgHeight + 2) = 1 Then

                    Dim r As New Rectangle

                    With r
                        .X = imgWidth
                        .Y = imgHeight
                    End With

                    For rectWidth As Integer = imgWidth To bow.GetUpperBound(0)
                        If bow(rectWidth, imgHeight) = 0 Then
                            r.Width = bow(rectWidth - 1, imgHeight)
                        End If
                    Next

                    For rectHeight As Integer = imgHeight To bow.GetUpperBound(1)
                        If bow(imgWidth, rectHeight) = 0 Then
                            r.Height = bow(rectHeight - 1, imgHeight)
                        End If
                    Next

                    rects.Add(r)
                End If
            End If
        Next
    Next

此外,数组必须能够拥有多个正方形。


1
你能否提供更多关于你的问题的细节,而不仅仅是“它没有返回任何东西”?你尝试过什么? - JoshD
当我尝试添加断点时,但查找宽度和高度的循环始终返回0。 - giodamelio
@giodamelio:这是作业吗?如果不是,那么它是用来做什么的,为什么要做? - JoshD
4
如果二维数组(7×9)全部填满了1,那么它应该返回756个可能的矩形列表吗? - Sheldon L. Cooper
@JoshD 不,这不是家庭作业,由于某种原因它被自动标记了。该数组是从一个文件中读取的,该文件是由另一个程序创建的,最初该程序使用拖放接口将正方形放在画布上创建了该文件。 - giodamelio
@Sheldon L. Coope 是的,应该这样。 - giodamelio
1个回答

3
这是我会做的方法:
def rectangles(grid):
  rows = len(grid)
  cols = len(grid[0])

  hor_ones = [[0]] * rows
  for r in range(rows):
    for c in range(cols):
      hor_ones[r].append(hor_ones[r][c] + grid[r][c])

  ver_ones = [[0]] * cols
  for c in range(cols):
    for r in range(rows):
      ver_ones[c].append(ver_ones[c][r] + grid[r][c])

  ret = []
  for r1 in range(rows):
    for c1 in range(cols):
      for r2 in range(r1+1, rows):
        for c2 in range(c1+1, cols):
          if all_ones(hor_ones[r1], c1, c2) and all_ones(hor_ones[r2], c1, c2) and all_ones(ver_ones[c1], r1, r2) and all_ones(ver_ones[c2], r1, r2):
            ret.append((r1, c2, r2, c2))
  return ret

def all_ones(ones, x, y):
  return ones[y+1] - ones[x] == y - x + 1

请注意:
- `hor_ones[r][c]` 表示第 r 行前 c 列中的 1 的数量。 - `ver_ones[c][r]` 表示第 c 列前 r 行中的 1 的数量。
因此,第 `r` 行在列 `c1` 和 `c2`(包括两端)之间的 1 的数量为:
`hor_ones[r][c2+1] - hor_ones[r][c1]`
编辑:
以下是 Java 实现的解决方案,或许更易于您理解和实现 VB.NET:
public static List<Rectangle> findRectangles(int[][] grid) {
    int rows = grid.length;
    int cols = grid[0].length;

    int[][] horOnes = new int[rows][cols+1];
    for (int r = 0; r < rows; r++)
        for (int c = 0; c < cols; c++)
            horOnes[r][c+1] = horOnes[r][c] + grid[r][c];

    int[][] verOnes = new int[cols][rows+1];
    for (int c = 0; c < cols; c++)
        for (int r = 0; r < rows; r++)
            verOnes[c][r+1] = verOnes[c][r] + grid[r][c];

    List<Rectangle> ret = new ArrayList<Rectangle>();
    for (int r1 = 0; r1 < rows; r1++)
        for (int c1 = 0; c1 < cols; c1++)
            for (int r2 = r1+1; r2 < rows; r2++)
                for (int c2 = c1+1; c2 < cols; c2++)
                    if (allOnes(horOnes[r1], c1, c2) && allOnes(horOnes[r2], c1, c2) && allOnes(verOnes[c1], r1, r2) && allOnes(verOnes[c2], r1, r2))
                        ret.add(new Rectangle(r1, c1, r2, c2));
    return ret;
}

private static boolean allOnes(int[] ones, int x, int y) {
    return ones[y+1] - ones[x] == y - x + 1;
}

非常感谢,但是可以有人将其翻译成VB.NET吗? - giodamelio
1
@giodmaelio,Python是一门比VB更好学的语言。引用Dijkstra的话说,“教授BASIC应该被视为犯罪行为:它会使人的思维永久性受损。”你会注意到解决你问题的人并不是VB程序员。 - aaronasterling
1
@Sheldon L. Cooper - 好的,我假设你正在使用标准的Java矩形。无论如何,我相信如果你打印出你的verOnes或horOnes的结果,你会发现它向右和向下扩展不正确,从而创建了额外的矩形。 - Nescio
@Nescio:你能提供一个小的输入网格,让我的代码失败吗? - Sheldon L. Cooper
@Nescio:我的程序适用于你的情况。它输出:[(0,0,8,9), (2,2,6,7)]。 - Sheldon L. Cooper
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接