避免调用堆栈错误

时间:2015-02-21 08:06:20

标签: javascript recursion callstack

我知道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]);
        }
    }
}

这是一个画布应用程序。

x_y只是调用fill的x和y坐标。

setPx在给定坐标的画布上打印一个矩形。

getPx获取画布矩形的颜色,给定它的坐标

pref.color是用户为setPx

选择的颜色

这个功能可以在没有递归的情况下完成吗?

1 个答案:

答案 0 :(得分:1)

这按顺序填写:

  • 左,
  • 右,

(除非我的坐标系统错误)。

使用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之前。