我知道超出调用堆栈大小
意味着什么,但我需要一种解决方法。
当我调用这个递归函数时我得到它
function fill(x_y) {
var locColor = getPx(x_y[0], x_y[1]);
if (locColor != pref.color) {
setPx(x_y[0], x_y[1], pref.color);
if (getPx(x_y[0] - 1, x_y[1]) == locColor) {
fill([x_y[0] - 1, x_y[1]]);
}
if (getPx(x_y[0], x_y[1] - 1) == locColor) {
fill([x_y[0], x_y[1] - 1]);
}
if (getPx(x_y[0] + 1, x_y[1]) == locColor) {
fill([x_y[0] + 1, x_y[1]]);
}
if (getPx(x_y[0], x_y[1] + 1) == locColor) {
fill([x_y[0], x_y[1] + 1]);
}
}
}
它用于 Canvas 应用程序。
x_y
只是调用 fill 的 x 和 y 坐标。
setPx
在给定坐标的 Canvas 上打印一个矩形。
getPx
获取给定坐标的 Canvas 矩形的颜色
pref.color
是用户为 setPx
选择的颜色
这个函数可以不用递归来完成吗?
最佳答案
按顺序填写:
- 左,
- 顶部,
- 对,
- 底部
(除非我的坐标系错误)。
使用x_y
列表进行处理,就可以不用递归来解决;您可以使用列表来存储下一次调用的参数,而不是使用堆栈进行递归。
function fill(x_y) {
var todo = [x_y];
var iniColor = getPx(x_y[0], x_y[1]);
while (todo.length) {
var curr = todo[0];
var locColor = getPx(curr[0], curr[1]);
todo = todo.slice(1);
if (locColor != iniColor) { continue; }
if (locColor == pref.color) { continue; }
setPx(curr[0], curr[1], pref.color);
todo.push([curr[0]-1,curr[1] ]);
todo.push([curr[0], curr[1]-1]);
todo.push([curr[0]+1,curr[1] ]);
todo.push([curr[0], curr[1]+1]);
}
}
更新:2015-03-01
从评论来看,由于迭代次数的原因,这不如问题中的算法。在这个 block 中,我没有提前检查条件,这意味着它们被添加到 todo
列表中,即使它们可能不是好的候选者。当稍后处理该点时,会检查条件。
todo.push([curr[0]-1,curr[1] ]);
todo.push([curr[0], curr[1]-1]);
todo.push([curr[0]+1,curr[1] ]);
todo.push([curr[0], curr[1]+1]);
解决方案:早在问题中检查;在调用push
之前。
关于javascript - 避免调用堆栈错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28643604/