[英]Correct error or transform code to recursive function to evaluate matrix
I need a function that separates all the "islands" or regions of a matrix that are formed by 1s. 我需要一个函数来分隔所有“岛”或由1组成的矩阵区域。 In my example it works correctly, but there are some "special" cases where it fails (as in the example case). 在我的示例中,它可以正常工作,但是在某些“特殊”情况下它会失败(如示例情况)。
How can I correct this error? 我该如何纠正该错误? or transform this function into a recursive function. 或将此函数转换为递归函数。 Let the for travel through the matrix and in the position that is a 1, call the recursive function and evaluate all the points around it. 让for行进穿过矩阵并处于1的位置,调用递归函数并计算其周围的所有点。
var matrix = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 1, 1, 1, 1, 0, 0, 0], [1, 1, 0, 1, 0, 0, 0, 1, 0, 0], [1, 0, 0, 1, 0, 0, 0, 1, 0, 0], [0, 0, 1, 1, 0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 0, 0, 0, 1, 1, 0], [0, 1, 0, 1, 0, 0, 0, 1, 1, 1], [0, 1, 0, 1, 1, 0, 0, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ]; var contFilas = matrix.length; var contColumnas = matrix[0].length; var canvas = document.querySelector("canvas"); var ctx = canvas.getContext("2d"); var sz = 20; var regions = []; var regionCollection = []; canvas.width = sz * contColumnas; canvas.height = sz * contColumnas; ctx.fillStyle = "silver"; ctx.fillRect(0, 0, canvas.width, canvas.height); for (var y = 0; y < contFilas; y++) { var regionline = []; regions.push(regionline); for (var x = 0; x < contColumnas; x++) { var pixelRegion = 0; regionline[x] = 0; if (matrix[y][x] === 1) { // check previous row if (y) { if (matrix[y - 1][x]) { pixelRegion = regions[y - 1][x]; } else if (x && matrix[y - 1][x - 1]) { pixelRegion = regions[y - 1][x - 1]; } else if (x + 1 < contColumnas && matrix[y - 1][x + 1]) { pixelRegion = regions[y - 1][x + 1]; } } // check current row if (x && matrix[y][x - 1]) { pixelRegion = regions[y][x - 1]; } // if not connected, start a new region if (!pixelRegion) { regionCollection.push([]); pixelRegion = regionCollection.length; } // remember region regionline[x] = pixelRegion; regionCollection[pixelRegion - 1].push([x, y]); // paint it ctx.fillStyle = "black"; ctx.fillRect(x * sz + 1, y * sz + 1, sz - 2, sz - 2); } ctx.fillStyle = "white"; ctx.fillText(pixelRegion, x * sz + 8, y * sz + 13); } } document.querySelector("#result").innerHTML = JSON.stringify(regionCollection);
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>getUserMedia</title> </head> <body> <canvas></canvas> <div id="result"></div> </body> </html>
In the example , region 2 and 3 must be only one (region 2). 在示例中 ,区域2和3必须仅是一个(区域2)。 That is, there will be 2 different regions. 也就是说, 将有2个不同的区域。 What is my error in the code? 我的代码有什么错误? How can I correct it? 我该如何纠正?
I think your problem is you're trying to do this in one pass of the array, which is not really possible (depending on what exactly you count as "one pass"). 我认为您的问题是您试图在数组的一次通过中执行此操作,这实际上是不可能的(取决于您确切地算作“一次通过”)。
The simplest algorithm is probably to loop through the array and where you see a 1
perform a flood-fill operation. 最简单的算法可能是遍历数组,您会看到1
执行泛洪填充操作。 Any pixel hit by the flood fill would be stored in a region and then ignored by the rest of your loop. 泛洪填充命中的任何像素都将存储在一个区域中,然后循环的其余部分将忽略它们。 Flood fill is computationally fairly slow, but it's well understood and there is a lot of code out there for it. 泛洪填充在计算上相当慢,但是众所周知,并且为此准备了很多代码。
Given you already have this code, though, I expect you'll end up with a faster solution just by taking the regionCollection
object you have and checking which regions touch. 但是,鉴于您已经有了这段代码,我希望您仅通过获取拥有的regionCollection
对象并检查接触哪些区域,就能得到一个更快的解决方案。 If any do, combine them. 如果有,请结合使用。 It will be less readable and probably more code than using flood-fills though, so it depends what you want to optimise for. 但是,与使用泛洪填充相比,它的可读性较差,并且代码可能更多,因此它取决于您要优化的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.