作为练习,我实现了一个简单的像素编辑器。模式之一是使用递归解决方案的洪水填充。它在小于约40x40像素的网格大小上正常工作。但是,当在较大的网格尺寸(例如64x64)上进行测试时,控制台仅会覆盖部分板子,控制台将显示错误Uncaught RangeError: Maximum call stack size exceeded
。当然,这表明已超过给定浏览器的硬编码调用堆栈大小。对于Chrome,64x64存在问题。对于Firefox则没有。
令我感到惊讶的是,我认为直接执行洪水填充会导致这样的错误,使我认为自己做错了什么。更令人困惑的是,错误不是在Chrome中一致生成的。让我解释一下-当我第一次打开包含我的应用的网页并尝试进行泛洪填充时,总是会产生错误。当我清理板子(将所有div单元都设置为“白色”)并再次尝试填充填充功能时,板子通常会完全填满。
在解决问题的同时,我还在FloodFill函数内部包含了一个计数器变量,每次调用该函数时,该计数器变量都会增加一个。对于第一次运行(导致失败),它的值约为4000。清除板并再次尝试后,其达到约16,000,板已完全装满。这似乎消除了任何关于我清除木板的方式会降低递归深度的想法。
所以... 1)知道这里发生了什么吗?和2)我编写算法的工作做得不好吗?
假设我的算法有误,我仍然想知道1)的答案。为什么结果看似不确定。
function floodFill(xCoordinate, yCoordinate, fillColor, regionColor) {
//checks to make sure that there is a cell at the specified coordinate
if(!(row[yCoordinate] && row[yCoordinate][xCoordinate])) {
return
}
//checks if cell is already filled with the appropriate color
else if(row[yCoordinate][xCoordinate].style.backgroundColor === fillColor) {
return
}
//checks to see if this cell is apart of the region that is SUPPOSED to be colored
else if(row[yCoordinate][xCoordinate].style.backgroundColor !== regionColor) {
console.log("nope: not fill region");
return
}
//changes the color of the current cell if the above conditions don't triger a return
brush.prototype.changeCellColor(xCoordinate, yCoordinate);
//creates a variable storing the displacment vectors that specify which cells to check next
var coordinates = [
[0, -1],
[1, 0],
[0, 1],
[-1, 0]
];
// recursivley runs the floodFill function of each of the cells specified by the displacement vectors
coordinates.forEach(function(element){
floodFill(xCoordinate + element[0], yCoordinate + element[1], fillColor, regionColor);
});
}