【问题标题】:Can you explain this recursive solution from Chap 3 Eloquent js? [duplicate]你能从第 3 章 Eloquent js 中解释一下这个递归解决方案吗? [复制]
【发布时间】:2015-01-28 09:26:33
【问题描述】:

我正在阅读 eloquent javascript 的第 3 章,并且刚刚介绍了递归,我正在尝试围绕这个概念来思考。

也有人能解释一下函数 find 中的第二个参数 history 吗?

历史已经定义了吗?

考虑这个难题:从数字 1 开始,反复加 5 或乘以 3,可以产生无限数量的新数字。你将如何编写一个函数,给定一个数字,试图找到一系列产生该数字的加法和乘法?例如,数字 13 可以先乘以 3,然后再加两次 5,而数字 15 则根本达不到。

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

【问题讨论】:

  • 请记住,history 只是一个字符串,仅此而已。
  • 在这些情况下,我发现一两个console.log() 可以真正解决问题。

标签: javascript recursion


【解决方案1】:

console.log 将打印 findSolution(24) 返回的值,其中 24 是目标。

现在,当函数 findSolution() 执行时,它调用(调用)函数“find”,并带有 2 个参数:start = 1,history = “1”,然后返回要打印的内容。

“return”发送回调用设置的地方。意思是 find() 在 findSolution() 中被调用,因此 return 将返回一个在 findSolution 中被调用的值。

在我们的例子中:

如果开始 === 目标

return history //(to findSolution. let's call it "H")
return H to console.log() // prints 1

else if start > target

return null //(to findSolution, let's call it N)
return N to console.log() // prints null

否则如果 start 小于 target, 返回一个 ||乙

A = find(start + 5, "(" + history + " + 5)")
B = find (start * 3, "(" + history + " * 3)")

意思是如果A是真的则返回A,否则返回B; 在函数返回之前计算 A 或 B。

让我们一步一步来:

find 将被一次又一次调用,start 参数递增 5 即:

return find(1, "1")    //  start = 1,   history = "(1 + 5)"    
return find(6, history)   //   start = 6,   history = "(1 + 5 ) + 5"   
return find(11, history)    //  start = 11,   history = "(1 + 5) + 5 ) + 5"   
return find(16, history)    //  start = 16,   history = "(1 + 5) + 5 ) + 5 ) + 5"   
return find(21, history) start = 21,   history = "(1 + 5) + 5 ) + 5 ) + 5 ) + 5"   

现在下一个值将是 26。由于 26 > 22,“find”将返回 B

return find(63, history) start = 21 * 3 =  63,      
//since 63 > 24,  "null" is returned where start = 16,    

start 是 16 而不是 63,因为它是一个参数。它没有改变,并且对调用期间发生的增量 5 一无所知。

find(21*3, history) , 48 > 24 所以返回 null where start = 11
find(11 *3, history) , 33 > 24 所以返回 null where start = 6
find(6*3, history) , start = 18 和 18 返回查找(18 + 5,历史)
return find (23 + 5, history) 28 > 24, A 为空,B 被评估

... 以此类推,直到 start 等于 24

【讨论】:

    【解决方案2】:

    在调用函数find 时指定历史记录。你不能调用函数find 而不提供历史值。请记住,该函数在被调用之前不会运行,因此在return find(1, "1"); 行上告诉它其值为"1" 之前,history 不会获得值。变量history 定义为每当@987654325 时逗号后面的东西@ 被调用。

    【讨论】:

      【解决方案3】:

      啊,我记得我用头撞这个很久了……

      作者在函数findSolution里面定义了函数find,比较混乱

      如果我这样重写它,你会得到它:

      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)");
      }
      
      function findSolution(target) {
        return find(1, "1");
      }
      
      console.log(findSolution(24));
      

      【讨论】:

        猜你喜欢
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多