【问题标题】:Finding Squares in an array在数组中查找正方形
【发布时间】:2010-10-09 00:47:53
【问题描述】:

我有一个充满 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

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

【问题讨论】:

  • 除了“它只是不返回任何东西”之外,您能否提供更多关于您的问题的详细信息?你试过什么?
  • 当我尝试添加断点时,找到宽度和高度的循环总是返回 0
  • @giodamelio:这是作业吗?如果不是,它的用途是什么?为什么?
  • 如果二维数组(7x9)是满的怎么办?它应该返回 756 个可能的矩形列表吗?
  • @JoshD 不,由于某种原因,它不是家庭作业,它被自动标记了。该数组是从一个由不同程序创建的文件中读取的,该程序最初是通过拖放界面制作文件,以便在画布上放置正方形。

标签: vb.net arrays algorithm


【解决方案1】:

我会这样做:

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] 是数量 前 c 列中的第 r 行。
  • ver_ones[c][r] 是数量 前 r 行中 c 列中的那些。

因此,r 行中以及c1c2(含)列之间的个数为:

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。
  • 我真的不知道该怎么处理它。
  • @giodmaelio Python 是一种比 VB 更好的学习语言。引用Dijkstra,“...... BASIC 的教学应该被视为刑事犯罪:它残害了无法恢复的思想。”您会注意到解决您问题的人不是 VB 程序员。
  • @Sheldon L. Cooper - 干得好!不幸的是, Rectangle 的构造函数需要宽度和高度——而不是右下角,所以你需要修复你的实例化。此外,您的 horOnes 和 verOnes 不会重置为零 - 请参阅我的修复答案。
  • @Sheldon L. Cooper - 好的,我假设您使用的是标准的 Java 矩形。无论如何,我相信如果您打印出您的 verOnes 或 horOnes 的结果,您会发现它不正确地延伸到右侧和底部,从而创建了额外的矩形。
猜你喜欢
  • 2014-01-01
  • 1970-01-01
  • 2017-11-09
  • 1970-01-01
  • 1970-01-01
  • 2015-09-05
  • 1970-01-01
  • 1970-01-01
  • 2011-12-05
相关资源
最近更新 更多