【问题标题】:How this code returns this value?此代码如何返回此值?
【发布时间】:2017-05-20 13:07:29
【问题描述】:

我正在通过阅读一本书来学习 JavaScript。我试图理解功能。我已经按照书上写了一段代码。但我不明白这段代码如何返回值。当我尝试更改函数值时,返回 null。

请任何人帮助我理解else的代码 这是代码

function solution(a){
    function search(c, d){
        if(c == a) return d;
        else if(c > a) return null;
        else return search(c + 5, "("+ d + " + 5)") || search(c*3, "("+ d + " * 3 )");
    }
    return search(1, "1")
}
console.log(solution(13));

它返回这个值(((1 * 3 ) + 5) + 5)

谢谢

【问题讨论】:

  • 提出问题时,最好为人们提供一些背景信息。这来自于书Eloquent JavaScript,在处理递归时。其实,你可以在书中找到很好的解释。
  • 对于尝试回答的人来说,使用该函数的示例是这样的:“考虑这个谜题:从数字 1 开始,反复加 5 或乘以 3,无限量的可以产生新的数字。你将如何编写一个函数,给定一个数字,尝试找到产生该数字的加法和乘法序列?"

标签: javascript function return


【解决方案1】:

递归在这里进行。我认为你理解这个 sn-p 的最好方法是打开控制台并点击下面的运行 sn-p。我在合适的位置添加了调试点,方便大家查看。

祝你好运。

function solution(a){
    debugger;
    function search(c, d){
       debugger;
        if(c == a) return d;
        else if(c > a) return null;
        else return search(c + 5, "("+ d + " + 5)") || search(c*3, "("+ d + " * 3 )");
    }
    return search(1, "1")
}
console.log(solution(13));

【讨论】:

  • 感谢您的回答。我已经在我的 chrome 浏览器上运行了代码。我得到了结果。但我可以找出这个结果是如何返回的。如果我想更改cd 的值,代码将返回null。我需要解释返回值。
【解决方案2】:

我不确定我是否理解这个问题,但我可以帮助解释一下代码。

首先调用解决方案(13),它返回递归函数的答案。

在第一次迭代期间,它检查是否 1 == 13,如果是则返回“1”。由于不是,它检查 1 是否大于 13。不是,所以它返回 search(6, "(1 + 5)"。

在第二次通过期间,它会执行相同的检查。 6 仍然不是 13,6 仍然不大于 13。所以它返回 search(11,"((1 + 5) + 5)")。

模式继续进行第三次迭代。在第三次迭代之后,16 现在大于 13,因此它返回 null。

return search(c + 5, "("+ d + " + 5)") || search(c*3, "("+ d + " * 3 )");

变成

return null || search(c*3, "("+ d + " * 3 )");

管道运算符用于过滤掉假值,例如 undefined、null、false 和 0。如果第一个值为 false,它会尝试第二个值。现在它调用

search(11*3, "(((1 + 5) + 5) * 3 )")

search(33, "(((1 + 5) + 5) * 3 )")

自 33 > 13 后再次返回 null。

else if(c > a) return null;

所以递归函数展开了另一个层次。现在是

search(6*3, "((1 + 5) * 3 )")

18 仍然高于 13,所以我们展开另一个级别。

search(1*3, "(1 * 3)")

现在 3 又小于 13,所以我们使用 || 的左侧重新滚动循环。运算符会将我们的数字加 5。

search(3 + 5, "((1 * 3) + 5)")

8 仍然小于 13,所以我们再重复一遍。

search(8 + 5, "(((1 * 3) + 5) + 5)")

最后,if(c == a) return d; 为真,所以我们返回 d 或“(((1 * 3) + 5) + 5)”。所有的循环都很快再次展开。

希望这有助于您了解循环如何展开和重新展开。

【讨论】:

    【解决方案3】:

    此代码仅使用 + 5 和 * 3 生成一个等于参数“a”的方程。在求解函数中,搜索函数被调用,直到参数“d”变为等价于“a” .

    将“d”视为历史,每次调用搜索时都会更新。现在让我们打破 else 代码。

    if c != a 
      check whether "c + 5" can be equivalent to "a" or less than "a"
        if "c + 5" is greater than a then
          return "null" to give a chance to "c * 3"
        else
          update "d" by d = d + "+ 5"
      OR
      check whether "c * 3" can be equivalent to "a" or less than "a"
        if "c * 3" is greater than a then
          return "null" to give a chance to "c * 3"
        else
          update "d" by d = d + "* 3"
    if c == a
      return d
    

    返回 null 将有机会执行其他测试。相同的过程将一直持续到“d”等价于“a”。

    【讨论】:

      【解决方案4】:

      珐琅,

      像这样的递归函数有时很难破译。我建议添加一些日志记录(console.log)来跟踪变量和调用。即使调试了递归函数的嵌套,也很难理解。

      话虽如此,修改你的代码有点像这样:

      function solution(a) {
          function search(c, d) {
              console.log(JSON.stringify({a,c,d}));
              if (c == a)
                  return d;
              else if (c > a)
                  return null;
              else
                  return search(c + 5, "(" + d + " + 5)") || search(c * 3, "(" + d + " * 3 )");
          }
          return search(1, "1")
      }
      

      我们在运行解决方案时得到这个(13) 我们得到:

      First call -> {"a":13,"c":1,"d":"1"}
      {"a":13,"c":6,"d":"(1 + 5)"}
      {"a":13,"c":11,"d":"((1 + 5) + 5)"}
      {"a":13,"c":16,"d":"(((1 + 5) + 5) + 5)"}
      {"a":13,"c":33,"d":"(((1 + 5) + 5) * 3 )"}
      {"a":13,"c":18,"d":"((1 + 5) * 3 )"}
      {"a":13,"c":3,"d":"(1 * 3 )"}
      {"a":13,"c":8,"d":"((1 * 3 ) + 5)"}
      {"a":13,"c":13,"d":"(((1 * 3 ) + 5) + 5)"}
      

      我们可以看到“c”等于“a”,然后返回“d”,其值为“(((1 * 3) + 5) + 5)”。

      例如,将其与正在运行的解决方案 (12) 进行比较:

      First call -> {"a":12,"c":1,"d":"1"}
      {"a":12,"c":6,"d":"(1 + 5)"}
      {"a":12,"c":11,"d":"((1 + 5) + 5)"}
      {"a":12,"c":16,"d":"(((1 + 5) + 5) + 5)"}
      {"a":12,"c":33,"d":"(((1 + 5) + 5) * 3 )"}
      {"a":12,"c":18,"d":"((1 + 5) * 3 )"}
      {"a":12,"c":3,"d":"(1 * 3 )"}
      {"a":12,"c":8,"d":"((1 * 3 ) + 5)"}
      {"a":12,"c":13,"d":"(((1 * 3 ) + 5) + 5)"}
      {"a":12,"c":24,"d":"(((1 * 3 ) + 5) * 3 )"}
      {"a":12,"c":9,"d":"((1 * 3 ) * 3 )"}
      {"a":12,"c":14,"d":"(((1 * 3 ) * 3 ) + 5)"}
      {"a":12,"c":27,"d":"(((1 * 3 ) * 3 ) * 3 )"}
      

      我们可以看到在最终调用中“c”大于“a”,在这种情况下函数返回null。

      我不是绝对肯定这回答了你的问题,但无论如何我认为使用日志记录,特别是像这样的函数将极大地帮助你进一步理解为什么你会得到这些结果。

      【讨论】:

        猜你喜欢
        • 2012-06-07
        • 1970-01-01
        • 2013-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多