Kotlin中getOrPut异常:f1正常计算斐波那契数f2仅返回0/1
这事儿有点意思——从代码上看,f1和f2的逻辑理论上是等价的,但如果你的f2真的只返回0和1,大概率是某个细节出了问题。先给你拆解下核心逻辑,再排查可能的原因:
先看两个函数的核心逻辑
不管是f1还是f2,都是用记忆化递归(借助MutableMap缓存已计算的斐波那契数)来避免重复计算:
- 默认参数里的map初始化了基础值
0→0和1→1 - 递归调用时都传递了同一个map对象,确保缓存能在递归过程中共享
- 两者的差异只是写法:f1把
n-1和n-2的结果先存在变量里再相加,f2直接把两个getOrPut的结果相加,逻辑上完全一致
为什么你会觉得f2仅返回0、1?
我猜可能是这几个原因:
1. 测试的n值刚好是前几项(误解)
斐波那契数列的前几项就是0, 1, 1, 2, 3, 5...,如果只测试了n=0、1、2,得到的结果确实是0、1、1,看起来像“仅返回0和1”。但你试试n=3,正常的f2应该返回2;n=5返回5,完全符合预期。
2. 递归调用时没传递map参数(代码笔误)
如果你的f2代码里,递归调用写成了f2(n-1)而不是f2(n-1, map),那每次递归都会创建一个新的默认map(只包含0和1),导致缓存无法共享。不过这种情况还是会返回大于1的值(比如n=3返回2),只是效率极低(相当于没有记忆化的普通递归)。
3. 默认map初始化错误
如果默认参数里的map没有正确初始化0→0和1→1(比如写成了mutableMapOf()),那递归会进入无限循环(计算n=0时会调用f2(-1),以此类推),但不会返回0或1。
验证结果
我把你的代码放到Kotlin环境里运行,f2(5)返回5,f2(10)返回55,和f1的结果完全一致,说明逻辑本身没问题。
内容的提问来源于stack exchange,提问作者David Soroko
相关产品推荐
相关产品推荐

