以下函数(f1
)按预期计算Fibonacci数:
fun f1(n: Int, map: MutableMap<Int, Int> = mutableMapOf(Pair(0, 0), Pair(1, 1))): Int =
map.getOrPut(n) {
val a = map.getOrPut(n - 1) { f1(n - 1, map) }
val b = map.getOrPut(n - 2) { f1(n - 2, map) }
a + b
}
但是此版本f2
仅返回0,1值:
fun f2(n: Int, map: MutableMap<Int, Int> = mutableMapOf(Pair(0, 0), Pair(1, 1))): Int =
map.getOrPut(n) {
map.getOrPut(n - 1) { f2(n - 1, map) }
+
map.getOrPut(n - 2) { f2(n - 2, map) }
}
看起来f2
只占用第一个“分支”:map.getOrPut(n - 1) { f2(n - 1, map) }
而不是第二个。
我知道f2
可以像这样修复:
fun f2(n: Int, map: MutableMap<Int, Int> = mutableMapOf(Pair(0, 0), Pair(1, 1))): Int =
map.getOrPut(n) {
(
map.getOrPut(n - 1) { f2(n - 1, map) }
+
map.getOrPut(n - 2) { f2(n - 2, map) }
)
}
为什么需要(..)
?
修改
正如@ user2357112和@emerssso所解释的那样,这是一个错误推断的分号的情况,以下是按预期工作的
fun f2(n: Int, map: MutableMap<Int, Int> = mutableMapOf(Pair(0, 0), Pair(1, 1))): Int =
map.getOrPut(n) {
map.getOrPut(n - 1) { f2(n - 1, map) } +
map.getOrPut(n - 2) { f2(n - 2, map) }
}
不酷。
答案 0 :(得分:4)
这是因为Kotlin在+
之后插入一个分号,并将+
映射到the unary plus operator,而不是您直观期望的正常双参数加运算符。
您可以通过执行转到声明(命令+单击Mac)来确认这一点,并将其结构化为您的问题。它需要我一元加上你的格式,正常加上加括号或没有换行。
这个意外的分号的结果是它将递归Fibonnacci生成,但从不做任何添加,默默地总是只返回getOrPut(n-2)
步的结果(因为它是函数中的最后一个语句)。