Java 如何计算0和1组成的2D矩阵中的矩形数?

Java 如何计算0和1组成的2D矩阵中的矩形数?,java,arrays,algorithm,Java,Arrays,Algorithm,我在这里搜索了很多帖子以及其他在线资源。它们中的大多数都提供了一种在二维矩阵中求矩形最大面积的解决方案,我理解这一点。但是,我很想知道如何在二维矩阵中找到矩形的数量,其中矩形由1s表示 更新: 抱歉,没有澄清矩形的分类情况-如果某个周长内的单元格用1s填充,则视为矩形 一些伪代码: for x_0 in rows: for x_1 > x_0 in rows: # symmetry-reduction: x_0 always "top" for y_0 in

我在这里搜索了很多帖子以及其他在线资源。它们中的大多数都提供了一种在二维矩阵中求矩形最大面积的解决方案,我理解这一点。但是,我很想知道如何在二维矩阵中找到矩形的数量,其中矩形由1s表示

更新: 抱歉,没有澄清矩形的分类情况-如果某个周长内的单元格用1s填充,则视为矩形

一些伪代码:

for x_0 in rows:
    for x_1 > x_0 in rows:     # symmetry-reduction: x_0 always "top"
        for y_0 in columns:
            for y_1 > y_0 in columns:  # symmetry reduction: y_0 always "left"
                if mat[x_0, y_0] == mat[x_0, y_1] == mat[x_1, y_0] == mat[x_1, y_1] == 1:
                    found rectangle!
请记住:它是伪代码(部分基于python风格),布尔求值在大多数语言中都不是这样工作的

对称性减少不仅可以提高性能,而且在计算时也很重要。有视觉上相等的矩形,其中x_0和x_1只是扮演不同的角色(左点和右点)。你必须决定如何计算这些

编辑:在Ole V.V.的上述评论之后,我意识到确实存在非常不同的解释。其中大多数都可以通过上面的伪代码实现,但需要在内部级别进行不同的检查。但那可能是你的工作(在某些情况下,可能会有更多优化的方法)

这里我假设,一个矩形是由4个角的1定义的

编辑:新定义矩形后,内部检查更改为:

if all(mat[x_0:x_1, y_0:y_1])  # python/numpy inspired pseudo-code!
因此,基本上您可以检查由4个边界点定义的所有值。这很容易解决你的问题

当然,你可以更有效率。添加一些二进制标志可能是明智的,它指示当前矩形(它们正在增长)是否仍然只填充了1。实际上,您可能需要2个二进制标志,每个维度1个。如果不是这样,您可以提前停止。

一些伪代码:

for x_0 in rows:
    for x_1 > x_0 in rows:     # symmetry-reduction: x_0 always "top"
        for y_0 in columns:
            for y_1 > y_0 in columns:  # symmetry reduction: y_0 always "left"
                if mat[x_0, y_0] == mat[x_0, y_1] == mat[x_1, y_0] == mat[x_1, y_1] == 1:
                    found rectangle!
请记住:它是伪代码(部分基于python风格),布尔求值在大多数语言中都不是这样工作的

对称性减少不仅可以提高性能,而且在计算时也很重要。有视觉上相等的矩形,其中x_0和x_1只是扮演不同的角色(左点和右点)。你必须决定如何计算这些

编辑:在Ole V.V.的上述评论之后,我意识到确实存在非常不同的解释。其中大多数都可以通过上面的伪代码实现,但需要在内部级别进行不同的检查。但那可能是你的工作(在某些情况下,可能会有更多优化的方法)

这里我假设,一个矩形是由4个角的1定义的

编辑:新定义矩形后,内部检查更改为:

if all(mat[x_0:x_1, y_0:y_1])  # python/numpy inspired pseudo-code!
因此,基本上您可以检查由4个边界点定义的所有值。这很容易解决你的问题


当然,你可以更有效率。添加一些二进制标志可能是明智的,它指示当前矩形(它们正在增长)是否仍然只填充了1。实际上,您可能需要2个二进制标志,每个维度1个。如果情况并非如此,您可以提前停止。

这里有一个非优化版本,应该会给出正确的结果:

int sum = 0;
for (int row = 0; row < n; row++) {
    for (int col = 0; col < m; col++) {
        // count all rectangles with top left corner at (row,col)
        int upperLimit = m; // this number sets the max width that rectangles with greater
                            // height can have (depends on the 1s in the rows above)
        for (int r = row; r < n && matrix[r][col] == 1; r++) {
            int c = col;
            for (; c < upperLimit && matrix[r][c] == 1; c++)
                sum++;
            upperLimit = c;
        }
    }
}
int和=0;
对于(int行=0;行
这是一个非优化版本,应该会给出正确的结果:

int sum = 0;
for (int row = 0; row < n; row++) {
    for (int col = 0; col < m; col++) {
        // count all rectangles with top left corner at (row,col)
        int upperLimit = m; // this number sets the max width that rectangles with greater
                            // height can have (depends on the 1s in the rows above)
        for (int r = row; r < n && matrix[r][col] == 1; r++) {
            int c = col;
            for (; c < upperLimit && matrix[r][c] == 1; c++)
                sum++;
            upperLimit = c;
        }
    }
}
int和=0;
对于(int行=0;行
矩形网格要计数,是角必须为1,还是边必须为1,还是矩形必须用1填充?@OleV.V.,我更新了我的问题。矩形网格要计数,是角必须为1,还是边必须为1,还是矩形必须用1填充?@OleV.V.,我更新了我的问题。@sashcha,谢谢你的回答。请检查我的最新问题。我已经澄清了矩形的分类细节。@sashcha,谢谢你的回答。请检查我的最新问题。我已经澄清了矩形的分类细节。我承认,在考虑是否为询问者编写代码时,总是需要找到一个平衡点。一般来说,我们说我们没有,主要是因为我们不想吸引“给我密码”之类的问题。我认为这是我们可以放心避免的情况之一,我们只能给出一个解释性的答案。我更喜欢伪码答案。不,在我看来10是正确的答案,我不知道你怎么得到8。如果我们从左到右,从上到下,它是4+1+2+2+1=10。另外,我认为伪代码的表述非常模糊,比必须的要复杂得多@谢谢你解释我的计数是怎么不正确的。我出错的一个原因是,您的代码有点棘手,应该得到比您的代码更好的解释