我想我已经掌握了Javascript中的递归,但希望在我正在阅读的一本书中对具体的递归代码有一些清晰的了解。
正如我所理解的,下面的代码正在进行几个步骤,如果您能够纠正我理解中的任何错误,我将非常感激:
if (start == target)语句告诉递归在找到解决方案时结束,并返回这种情况的历史记录。我不确定的是,为什么函数在下一次迭代中通过第一部分将5添加到(1 * 3),函数如何知道添加5,然后在下一次迭代中乘以3?为什么它不继续添加5,然后这样做,直到它太大并返回null?
function findSolution(target) {
function find(start, history) {
if (start == target)
return history;
else if (start > target)
return null;
else
return find(start + 5, "(" + history + " + 5)") ||
find(start * 3, "(" + history + " * 3)");
}
return find(1, "1");
}
console.log(findSolution(24));
// → (((1 * 3) + 5) * 3)发布于 2017-01-19 00:27:06
也许这让我们更清楚地知道了发生了什么。
我刚刚向depth-argument添加了一个find-function以确定递归深度,并添加了一个console.log()来记录所有递归调用。
function findSolution(target) {
//added a depth-property to show the recursion better
function find(start, history, depth) {
//simply log all calls in order
console.log("%s%d == %s", "| ".repeat(depth), start, history);
if (start == target)
return history;
else if (start > target)
return null;
else
return find(start + 5, "(" + history + " + 5)", depth+1) ||
find(start * 3, "(" + history + " * 3)", depth+1);
}
return find(1, "1", 0);
}
console.log(findSolution(24));
发布于 2017-01-19 00:04:12
其实你提到的每一个可能的案子都经过了。它继续添加5,直到它太大并返回null (在本例中为find(start + 5, "(" + history + " + 5)") === null (false) ),因此结果将来自另一个分支。
这真的很难解释,因为你需要理解执行堆栈,或者画一棵执行树。让我知道我能帮上什么忙
发布于 2017-01-19 00:32:27
下面是您的代码的一个版本,它将为您打印一个执行树,以便您可以跟随算法实际上正在尝试的所有不同排列:
function findSolution(target) {
function find(start, history, trace) {
trace.push(history)
if (start == target) {
console.log(trace.join(' => ') + ' => ' + start + ' == ' + target);
return history;
}
if (start > target) {
console.log(trace.join(' => ') + ' => ' + start + ' > ' + target);
return null;
}
return find(start + 5, "(" + history + " + 5)", [].slice.call(trace)) ||
find(start * 3, "(" + history + " * 3)", [].slice.call(trace));
}
return find(1, "1", []);
}
findSolution(24)下面是执行树:
1 => (1 + 5) => ((1 + 5) + 5) => (((1 + 5) + 5) + 5) => ((((1 + 5) + 5) + 5) + 5) => (((((1 + 5) + 5) + 5) + 5) + 5) => 26 > 24
1 => (1 + 5) => ((1 + 5) + 5) => (((1 + 5) + 5) + 5) => ((((1 + 5) + 5) + 5) + 5) => (((((1 + 5) + 5) + 5) + 5) * 3) => 63 > 24
1 => (1 + 5) => ((1 + 5) + 5) => (((1 + 5) + 5) + 5) => ((((1 + 5) + 5) + 5) * 3) => 48 > 24
1 => (1 + 5) => ((1 + 5) + 5) => (((1 + 5) + 5) * 3) => 33 > 24
1 => (1 + 5) => ((1 + 5) * 3) => (((1 + 5) * 3) + 5) => ((((1 + 5) * 3) + 5) + 5) => 28 > 24
1 => (1 + 5) => ((1 + 5) * 3) => (((1 + 5) * 3) + 5) => ((((1 + 5) * 3) + 5) * 3) => 69 > 24
1 => (1 + 5) => ((1 + 5) * 3) => (((1 + 5) * 3) * 3) => 54 > 24
1 => (1 * 3) => ((1 * 3) + 5) => (((1 * 3) + 5) + 5) => ((((1 * 3) + 5) + 5) + 5) => (((((1 * 3) + 5) + 5) + 5) + 5) => ((((((1 * 3) + 5) + 5) + 5) + 5) + 5) => 28 > 24
1 => (1 * 3) => ((1 * 3) + 5) => (((1 * 3) + 5) + 5) => ((((1 * 3) + 5) + 5) + 5) => (((((1 * 3) + 5) + 5) + 5) + 5) => ((((((1 * 3) + 5) + 5) + 5) + 5) * 3) => 69 > 24
1 => (1 * 3) => ((1 * 3) + 5) => (((1 * 3) + 5) + 5) => ((((1 * 3) + 5) + 5) + 5) => (((((1 * 3) + 5) + 5) + 5) * 3) => 54 > 24
1 => (1 * 3) => ((1 * 3) + 5) => (((1 * 3) + 5) + 5) => ((((1 * 3) + 5) + 5) * 3) => 39 > 24
1 => (1 * 3) => ((1 * 3) + 5) => (((1 * 3) + 5) * 3) => 24 == 24https://stackoverflow.com/questions/41731494
复制相似问题