【发布时间】:2021-06-26 00:20:25
【问题描述】:
基本上我要处理的是一个二维数组,它构成了网格上的像素。二维数组由数字 0 到 10 组成,代表每个像素的颜色。数字 0 表示一个像素未填充颜色,而所有数字 1 到 10 表示一个像素已填充颜色。我想弄清楚的是,当数组中的这些值形成一个矩形,然后获取每个单独矩形的左上角坐标 [x1, y1] 和右下角坐标 [x2, y2] 时。
这是我想要得到的坐标输出:
绿色1:
1:[x1:0][y1:0][x2:4][y2:2]
2:[x1:0][y1:3][x2:2][y2:5]
3:[x1:3][y1:5][x2:7][y2:5]
4: [x1: 10] [y1: 7] [x2: 12] [y2: 10]
5:[x1: 6] [y1: 13] [x2: 8] [y1: 15]
红色2:
1: [x1: 5] [y1: 0] [x2: 7] [y2: 2]
2: [x1: 10] [y1: 4] [x2: 15] [y2: 6]
3:[x1:13][y1:7][x2:15][y2:10]
4:[x1:1][y1:10][x2:5][y2:15]
蓝色 [3]:
1: [x1: 3] [y1: 3] [x2: 7] [y2: 4]
紫色 [4]:
1: [x1: 14] [y1: 0] [x2: 15] [y2: 1]
我使用的代码:
请注意,这只获取值为 1 的矩形的坐标。我怎样才能使它也适用于其他值?
const array = [
[1, 1, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 4, 4], //0
[1, 1, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 4, 4], //1
[1, 1, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0], //2
[1, 1, 1, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0], //3
[1, 1, 1, 3, 3, 3, 3, 3, 0, 0, 2, 2, 2, 2, 2, 2], //4
[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 2], //5
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2], //6
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2], //7
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2], //8
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2], //9
[0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2], //10
[0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], //11
[0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], //12
[0, 2, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], //13
[0, 2, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], //14
[0, 2, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0] //15
];
const W = array[0].length;
const H = array.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 += array[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 (array[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 (array[rect.y1][i] !== 1) {
rect.x2 = i - 1;
return rect;
}
for (let j = rect.y1; j <= rect.y2; ++j) {
if (array[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) {
array[j][i] = 2;
}
}
}
代码来自:Find the coordinates of all rectangles of contiguous 1s in a 2D array in Javascript
如果有人能帮我做这件事或提供一些代码,那真是太棒了!!!
【问题讨论】:
标签: javascript arrays matrix multidimensional-array