1

给定一个数字,程序应该返回一个仅使用 *3 或 +5 的操作序列来获取该数字,因此有两条路径可供选择。这个程序在调用自己时如何知道调用哪个函数?它如何知道每条路径调用了多少次。换句话说,我不明白如何使用OR操作员来确定find()要使用哪个调用以及每个调用有多少。

function findSequence(goal) {
    // we start at 1, and history is a string that will keep track of the operations
    function find(start, history) {
        // case when start and goal is 1.
        if (start == goal)
            return history; // return string containg 1
        // case when we build start past what we needed
        else if (start > goal)
            return null;
        else
            // Dont understand this part!
            return find(start + 5, "(" + history + " + 5)") ||
                find(start * 3, "(" + history + " * 3)");
    }
    return find(1, "1");
}

document.write(findSequence(13));
4

2 回答 2

3

运算符检查左操作数的||真值。有趣的是,||表达式的计算结果不是trueor false。如果真值为真,则表达式计算为该左操作数。如果不是,则计算为正确的操作数。例子:

> 5 || 10
5
> 5 || 0
5
> 0 || 10
10
> 0 || undefined
undefined

因此a || b实际上等价于a ? a : b。同样,a && b实际上等价于a ? b : a

> 0 && 10
0
> 0 && undefined
0
> 5 && 10
10
> 5 && undefined
undefined

非布尔值的真值在JavaScript 规范中确定:

  • 未定义 -> 假
  • 空 -> 假
  • String -> 如果为空字符串则为 False,否则为 True
  • 对象 > 真

编辑:哦,正如 mattedgod 指出的那样,一旦表达式计算为结果,则表达式的其余部分根本不会被计算。例如:

> function fail() { throw "I failed!"; }
> fail()
XXX "I failed!"
> 5 || fail()
5
> 0 && fail()
0

在上述情况下不会发生故障,但在以下情况下会发生:

> 0 || fail()
XXX "I failed!"
> 5 && fail()
XXX "I failed!"

因此,如果你有两次调用find()like find(...) || find(...),如果第一次调用的结果具有真值,那么它的结果将被返回,而第二次调用根本不会执行。如果第一次调用的结果有一个假真值,那么第二次调用将执行并且表达式计算结果是什么。

于 2013-03-25T16:37:46.317 回答
2

这依赖于 JavaScript(和许多其他语言)称为“短路”的属性。

如果您考虑一下,如果您正在评估某事为真并且它为A || B真,如果 A 为真,那么整个表达式将为真,检查 B 没有意义。反之则为真&&,如果 A 为假而您是评估A && B,整个表达式是错误的,所以没有必要打扰 B。

在您的示例中,如果第一次调用find成功,它将不会执行第二次。但是,如果第一次调用不成功(我猜它返回 false 或 null 或评估为 JS false 的东西),第二次调用将被执行。

于 2013-03-25T16:39:48.033 回答