简体   繁体   English

更正错误或将代码转换为递归函数以求矩阵

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM