在Javascript中找到2D数组中连续1的所有矩形的坐标 [英] Find the coordinates of all rectangles of contiguous 1s in a 2D array in Javascript

查看:48
本文介绍了在Javascript中找到2D数组中连续1的所有矩形的坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了无数问题,询问如何在2D数组中找到最大的连续矩形,还有一些询问矩形的数目,但是只有一个涉及查找所有矩形的坐标,宽度和高度的问题.在1s和0s的2D中覆盖1s区域所需的矩形.

I have found numerous questions asking about how to find the largest contiguous rectangle in a 2D array, and some that ask for the number of rectangles, but only one that deals with finding the coordinates, width, and height of all of the rectangles required to cover an area of 1s in a 2D of 1s and 0s.

问题(在2d块网格中查找矩形)有一个解决方案,但由于引用了外部代码块而很难遵循.

The question (Finding rectangles in a 2d block grid) has a solution but is difficult to follow since it references an external code block.

我正在处理组成字母像素的2D阵列:

I am dealing with 2D arrays that make up the pixels of letters:

0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0

0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0

0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0

0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0

0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0

0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0

0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0

0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0

0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0

0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0

0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0

0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0

0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0

0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0

0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0

0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0

0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0

0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0

所需的输出如下:

[[4,0,6,17],[7,0,16,2],[7,7,15,9],[7,15,15,17]]

[[4,0,6,17],[7,0,16,2],[7,7,15,9],[7,15,15,17]]

每个数组都包含左上角坐标和右下角坐标(任何获得左上角,宽度和高度的方法都可以使用).

Where each array contains the upper left hand coordinate and lower right hand coordinate (any method that gets upper left and width and height also works).

有人可以为先前提出的问题或其他可行的算法提供伪代码(或Javascript),还是为所需步骤提供更深入的说明?

Could someone provide the psudocode (or Javascript) for either the question previously asked or another algorithm that works, or provide a more in-depth explanation of the steps required?

推荐答案

这里是一种使用简单算法的方法.

Here is a way to do it with using a simple algorithm.

  1. 计算矩形覆盖的总面积-> A
  2. 尽管到目前为止找到的矩形的面积小于A
  1. Calculate the total area covered by rectangles -> A
  2. While the area of the rectangles found so far is smaller than A
  1. 找到一个新的矩形
  1. Find a new rectangle
  1. 找到左上角,扫描矩阵,然后在找到的第一个1处停止
  2. 找到右下角,从左上角开始,扫描矩阵,并在找到的第一个0处停止

  • 通过将每个单元格设置为1以外的其他内容来标记找到的矩形
  • 将其面积添加到累积面积中
  • 将矩形推入列表
  • const mat = [
      [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],//0
      [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],//1
      [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],//2
      [0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//3
      [0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//4
      [0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//5
      [0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//6
      [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],//7
      [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],//8
      [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],//9
      [0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//10
      [0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//11
      [0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//12
      [0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//13
      [0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//14
      [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],//15
      [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],//16
      [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0] //17
    ];
    
    const W = mat[0].length;
    const H = mat.length;
    
    // get the area covered by rectangles
    let totalRectArea = 0;
    for (let i = 0; i < W; ++i) {
      for (let j = 0; j < H; ++j) {
        totalRectArea += mat[j][i] > 0 ? 1 : 0;
      }
    }
    
    const rects = [];
    let rectArea = 0;
    
    // find all rectangle until their area matches the total
    while (rectArea < totalRectArea) {
      const rect = findNextRect();
      rects.push(rect);
      markRect(rect);
      rectArea += (rect.x2 - rect.x1 + 1) * (rect.y2 - rect.y1 + 1);
    }
    
    console.log(rects);
    
    function findNextRect() {
      // find top left corner
      let foundCorner = false;
      const rect = { x1: 0, x2: W-1, y1: 0, y2: H-1 };
      for (let i = 0; i < W; ++i) {
        for (let j = 0; j < H; ++j) {
          if (mat[j][i] === 1) {
            rect.x1 = i;
            rect.y1 = j;
            foundCorner = true;
            break;
          }
        }
        if (foundCorner) break;
      }
      // find bottom right corner
      for (let i = rect.x1; i <= rect.x2; ++i) {
        if (mat[rect.y1][i] !== 1) {
          rect.x2 = i-1;
          return rect;
        }
        for (let j = rect.y1; j <= rect.y2; ++j) {
          if (mat[j][i] !== 1) {
            rect.y2 = j-1;
            break;
          }
        }
      }
      return rect;
    }
    
    // mark rectangle so won't be counted again
    function markRect({ x1, y1, x2, y2 }) {
      for (let i = x1; i <= x2; ++i) {
        for (let j = y1; j <= y2; ++j) {
          mat[j][i] = 2;
        }
      }
    }

    这篇关于在Javascript中找到2D数组中连续1的所有矩形的坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆