来自 Eloquent Javascript 的 Javascript 递归
Posted
技术标签:
【中文标题】来自 Eloquent Javascript 的 Javascript 递归【英文标题】:Javascript recursion from Eloquent Javascript 【发布时间】:2014-11-30 01:43:45 【问题描述】:所以这是来自 Eloquent javascript。我试图弄清楚这段代码是如何实际执行的。所以我们试图找到一种方法来通过加 5 或乘以 3 来达到目标数字,我们从数字 1 开始。所以,本质上,我们正在尝试找到一系列这样的加法和乘法来产生目标数字?例如,数字 13 可以先乘以 3,然后再加两次 5,而数字 15 则根本达不到。
这里是sn-p的代码:
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)
显然这就是我们调用findSolution(13)
时发生的情况:
为了更好地理解这个函数如何产生我们正在寻找的效果,让我们看看在寻找数字 13 的解决方案时对 find 的所有调用。
find(1, "1")
find(6, "(1 + 5)")
find(11, "((1 + 5) + 5)")
find(16, "(((1 + 5) + 5) + 5)")
too big
find(33, "(((1 + 5) + 5) * 3)")
too big
find(18, "((1 + 5) * 3)")
too big
find(3, "(1 * 3)")
find(8, "((1 * 3) + 5)")
find(13, "(((1 * 3) + 5) + 5)")
found!
问题: 1) 我很困惑当我们调用 findSolution(13) 时会发生什么。当我没有提供起始编号或历史编号时,第一行是如何找到 (1, "1") 的?代码是如何一步步降到一行的:
return find(1,"1")
代码如何到达那里? 2) 这是 OR 语句在递归中的操作方式吗?在递归检查中,Javascript 通常会在处理第二个分支之前探索 OR 语句的第一个分支吗?这条线是:
find(3, "(1 * 3)")
仅在以下所有分支之后检查:
find(6, "(1 + 5)")
未能返回解决方案?
【问题讨论】:
另见A clearer explanation for recursion and flow of execution in JavaScript?和How does this recursion work? 另见Why does this program keep on running after null is returned? 【参考方案1】:1) 如果您查看代码,函数“findSolution”由两部分组成:方法定义“find”和对该方法的调用“return find(1, "1")”。该定义本身不会产生计算,除非它被调用。因此,实际执行的第一个表达式是“find(1, "1")”。这是起点。
2) OR 语句按其阅读顺序执行,因此“find(start + 5, ...)”将首先执行,然后仅当它确实返回 null 时(即,它没有找到解决方案)下一条语句“find(start * 3, ...)”将被执行。由于递归,您可以在执行“*3”之前执行任意数量的“+5”,当然具体取决于目标。
【讨论】:
啊,我明白了,定义函数 find(parameter, parameter) 在被 return find(1,"1") 语句调用之前什么都不做。很酷。以上是关于来自 Eloquent Javascript 的 Javascript 递归的主要内容,如果未能解决你的问题,请参考以下文章
来自 SQL 的 Laravel Eloquent ORM 聚合函数
多个 Laravel Eloquent 关系未显示来自所有关系的数据
在 JavaScript 中检索 Eloquent 模型函数