避免调用堆栈错误
Avoiding call stack error
我知道 call stack size exceeded
是什么意思,但我需要一种解决方法。
当我调用这个递归函数时我明白了
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
只是调用填充的 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
从评论来看,由于迭代次数,这不如问题中的算法。在这个块中,我没有提前检查条件,这意味着它们被添加到 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
.
之前
我知道 call stack size exceeded
是什么意思,但我需要一种解决方法。
当我调用这个递归函数时我明白了
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
只是调用填充的 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
从评论来看,由于迭代次数,这不如问题中的算法。在这个块中,我没有提前检查条件,这意味着它们被添加到 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
.