首先你需要了解内部函数的返回值是如何工作的。
return func(A) || func(B)
如果 func(A) 不为 null,则返回,否则为 func(B)
现在我们的目标是 24,起点是find(1, 1)(触发递归函数的外部函数的返回值)
find(1, 1) 可能有两种可能的输出:
A: find(6, (1+5))
or
B find(3, (1*3))
B 将被搁置,除非我们从 A 获得 null 返回(或到达目标),所以我们继续 A,返回将是:
Aa: find(11, ((1+5)+5))
or
Ab: find(15, ((1+5)*3))
Ab 再次暂停,我们继续 Aa 将返回:
Aa1: find(16, (((1+5)+5)+5))
Aa2: find(33, (((1+5)+5)*3))
Aa2 大于目标 (24),因此它永远不会继续。所以我们继续使用 Aa1,它将返回 21,然后是 25,它通过了目标,因此返回 null。所以我们回到 Ab 返回 45 > target。所以A 无论如何都会返回null,现在我们试试B:
Ba: find(8, ((1*3)+5))
Bb: find(9, ((1*3)*3))
继续使用 Ba,然后返回:
Ba1: find(13, (((1*3)+5)+5))
Ba2: find(24, (((1*3)+5)*3))
我们继续使用 Ba1,它将返回 18,然后是 23,然后是大于目标的 28,因此为空。所以回到Ba2,即24 == target,然后完成计算并返回它的历史,即:
(((1*3)+5)*3)
jsfiddle DEMO
您可以看到所有端点的日志(达到 null 时或最终找到匹配时)。
编辑:
这是函数的执行方式:
//instead of find I use f
findSolution(24) >
f(1, 1) >
f(6, (1+5)) >
f(11, ((1+5)+5)) >
f(16, (((1+5)+5)+5)) >
f(21, ((((1+5)+5)+5)+5)) >
f(26, (((((1+5)+5)+5)+5)+5)) > NULL
f(63, (((((1+5)+5)+5)+5)*3)) > NULL
f(48, ((((1+5)+5)+5)*3)) > NULL
f(33, (((1+5)+5)*3)) > NULL
f(18, ((1+5)*3)) >
f(23, (((1+5)*3)+5)) >
f(28, ((((1+5)*3)+5)+5)) > NULL
f(69, ((((1+5)*3)+5)*3)) > NULL
f(54, (((1+5)*3)+5)) > NULL
f(3, (1*3)) >
f(8, ((1*3)+5)) >
f(13, (((1*3)+5)+5)) >
f(18, ((((1*3)+5)+5)+5)) >
f(23, (((((1*3)+5)+5)+5)+5)) >
f(28, ((((((1*3)+5)+5)+5)+5)+5)) > NULL
f(69, ((((((1*3)+5)+5)+5)+5)*3)) > NULL
f(54, (((((1*3)+5)+5)+5)*3)) > NULL
f(39, ((((1*3)+5)+5)*3)) > NULL
f(24, (((1*3)+5)*3)) > MATCH