javascript递归参数行为

时间:2014-12-14 16:00:36

标签: javascript recursion

我想列出所有可能的参数组合。我写了一个应该解决问题的递归算法。问题是我用作reurive参数的变量在递归调用之前不会保留它们的旧值。

问题

假设我有2个参数,其中包含以下可能的值:

P1 = A or B
P2 = C or D or E

我想找到可能的组合:

AC
AD
AE
BC
BD
BE

递归"解决方案"

var params = [];

var param1 = ['A', 'B', 'C'];
var param2 = ['E', 'F'];
var param3 = ['G', 'H', 'I'];

params.push(param1);
params.push(param2);
params.push(param3);

function r(ps, s) {
    console.log(ps.length + " " + s.length);
    if (ps.length == 0) {
        console.log(s);
        return;
    }
    var p = ps[0];
    for (idx in p) {
        s.push(p[idx]);
        console.log("Before call " + s);
        r(ps.slice(1), s);
    }
}

var sol = [];
r(params, sol);

JS Fiddle

运行时问题

运行程序时,s变量不断增长。前3次迭代给出:

Before call A
Before call A, E
Before call A, E, G

在第一次回调之后,我希望s变量包含AE,因为它是在调用之前的值。

1 个答案:

答案 0 :(得分:1)

要修复算法,您需要在从递归调用返回时从数组中弹出元素:

for (idx in p) {
    s.push(p[idx]);
    r(ps.slice(1), s);
    s.pop(); // remove the element once we are done with the recursion
}

但请注意,console.log(s)将显示对象的引用,这意味着在控制台中您会看到s为空,因为算法将在完成后快速完成s由于弹出而变空。要强制console.log打印内容而不是参考,您可以使用console.log(s.toString())

if (ps.length == 0) {
    console.log(s.toString());
    return;
}