为什么这个程序在返回 null 后继续运行? [英] Why does this program keep on running after null is returned?

查看:52
本文介绍了为什么这个程序在返回 null 后继续运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习递归,我了解程序通常是如何工作的,但我很困惑为什么当值(16)太大时程序在首次返回 null 后继续工作.

I'm learning recursion and I understand how the program generally works, but I'm confused why the program continues to work after null is first returned when the value, at 16, is too big.

基本上,下面的代码将运行,并在每次从 1,6,11 到 16 的 start 参数中添加 5.由于 16 > 13,它表示返回 null.当 JavaScript 在第 6 行说 return null 时,它如何知道要返回并尝试计算 13?

Basically the code below will run and add 5 to the argument for start each time from 1,6,11 to 16. Since 16 is > 13 it says to return null. How does JavaScript know to go back and try to calculate 13 when it just says return null on line 6?

我真的很感激任何帮助.这是我正在看的书中的代码:

I'd really appreciate any help. Here's the code from the book I'm looking at:

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(13)); 

推荐答案

罪魁祸首是:

  return find(start + 5, "(" + history + " + 5)") ||
         find(start * 3, "(" + history + " * 3)");

假设 start 等于 1,就像你的代码一样,我们的目标是 13.

Lets assume start is equal to 1 and, like with your code, our target is 13.

  1. find() 以我们的 1 开始调用.让我们称之为Find A.
  2. find() 到达上面的代码段,并使用新的 start1 + 5 (6) 再次触发.我们称之为Find B.
  3. Find B 也可以访问上面的代码段,并使用新的 start6 + 5 (11) 再次触发.我们称之为Find C.
  4. Find C 也可以访问上面的代码片段,并使用新的 start11 + 5 (16) 再次触发.我们称之为Find D.
  5. Find D 返回值 nullFind C.
  6. Find C 执行上述代码段的 OR 参数.find() 再次被触发,新的 start 值为 6 * 3 (18).我们称之为Find E.
  1. find() is called with our 1 to begin with. Lets call this Find A.
  2. find() gets to the snippet above and is triggered again with a new start value of 1 + 5 (6). Let's call this Find B.
  3. Find B also gets to the snippet above and is triggered again with a new start value of 6 + 5 (11). Let's call this Find C.
  4. Find C also gets to the snippet above and is triggered again with a new start value of 11 + 5 (16). Let's call this Find D.
  5. Find D returns the value null to Find C.
  6. Find C executes the OR parameter of the above snippet. find() is triggered again with a new start value of 6 * 3 (18). Let's call this Find E.

看看发生了什么?

  1. Find E,就像我们已故的朋友 Find D 返回值 nullFind C.
  2. Find C 现在返回值 nullFind B.
  3. Find B 执行上述代码段的 OR 参数.
  1. Find E, like with our deceased friend Find D returns the value null to Find C.
  2. Find C now returns the value null to Find B.
  3. Find B executes the OR parameter of the above snippet.

最终,当 null 以外的值返回到原始 Find A 调用时,您的递归将结束,但在到达原始值之前它还有一段路要走Find A 并最终返回一个值给我们的 findSolution() 函数.

Eventually your recursion will end when a value other than null is returned to your original Find A call, but it still has a way to go before it reaches the original Find A and finally returns a value to our findSolution() function.

对于每个 null 响应,都会进行一个新的 find() 调用.null 是一个假值.在返回真值之前(在本例中为您的 history 变量),将执行新的 find() 函数.当返回 history 变量时,它会被传递回调用函数,调用函数将其传递回调用函数,直到最终返回到我们的 Find A 函数将其传递回 findSolution() 函数的调用.

For every null response, a new find() call is made. null is a falsey value. Until a truthy value is returned (your history variable in this case), new find() functions will be executed. When the history variable is returned, it gets passed back to the calling function, which passes it back to its calling function, until eventually it makes it back to our Find A function call which passes it back to the findSolution() function.

您需要为此打开 JavaScript 控制台.

You'll need to open your JavaScript console for this.

var findIteration = 0;

function findSolution(target) {
  function find(start, history, caller) {
    var thisIteration = ++findIteration;
    console.log("Find Iteration " + thisIteration, "Start: " + start, "Called by: " + caller);
    if (start == target)
      return history;
    else if (start > target)
      return null;
    else
      return find(start + 5, "(" + history + " + 5)", thisIteration) ||
             find(start * 3, "(" + history + " * 3)", thisIteration);
  }
  return find(1, "1", 0);
}

console.log(findSolution(13));

我们的控制台输出如下所示:

Here's what our console output looks like:

被召唤"这是调用它的 find() 方法 - 就像 Find C(迭代 3)在我在开始时给出的文本示例.

The "Called By" here is the find() method that called it - just like how Find C (iteration 3) calls Find E (iteration 5) in the text example I was giving at the start.

总而言之,我们的 find() 函数在最终达到正确值之前被调用了 9 次.

All in all, our find() function was called 9 separate times before finally reaching the correct value.

这篇关于为什么这个程序在返回 null 后继续运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆