来自 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 模型函数

Laravel Eloquent - 来自相关数据的多个记录的列值的总和

无法获取加入多个 Eloquent 关系的数据

拉拉维尔 |使用 Eloquent hasManyThrough