我正在通过阅读一本书来学习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)
谢谢
答案 0 :(得分:0)
这里正在进行递归。我认为你理解这个片段的最好方法是打开控制台并点击下面的运行片段。我已在适当的位置添加了调试点,以便您查看。
祝你好运。
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));

答案 1 :(得分:0)
我不确定我是否理解这个问题,但我可以帮助解释一下代码。
首先调用solution(13),它返回递归函数的答案。
在第一次迭代期间,它检查1 == 13,如果是,则返回" 1"。由于它不是,它检查1是否大于13.它不是,所以它返回搜索(6,"(1 + 5)"。
在第二次通过期间,它会进行相同的检查。 6仍然不是13,6仍然不大于13.所以它返回搜索(11,"((1 + 5)+ 5)")。
模式继续进行第3次迭代。在第三次迭代之后,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>因此返回null。 13。
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)"。所有循环再次快速展开。
希望这可以帮助您了解循环展开和重新滚动的方式。
答案 2 :(得分:0)
此代码仅使用+ 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”。
答案 3 :(得分:0)
Enamul,
这样的递归函数有时难以破译。我建议添加一些日志记录(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。
我不是绝对肯定这会回答你的问题,但无论如何我认为使用日志特别是使用这样的函数会大大帮助你进一步理解为什么你会得到这些结果。