【发布时间】:2019-05-28 15:48:37
【问题描述】:
我有以下代码:
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
public class DynamicFib
{
private static Map<Integer, BigInteger> myMap = new HashMap<>();
static {
myMap.put(0, BigInteger.ZERO); //fibonacci(0)
myMap.put(1, BigInteger.ONE); //fibonacci(1)
}
public static BigInteger fibonacci(int x)
{
// System.out.println("x = [" + x + "]");
return myMap.computeIfAbsent(x, n -> fibonacci(n - 2).add(fibonacci(n - 1)));
}
public static void main(String[] args)
{
System.out.println("l = " + fibonacci(25));
System.out.println("myMap = " + myMap);
System.out.println("myMap = " + myMap.keySet().size());
}
}
控制台输出:
l = 75025
myMap = {0=0, 1=1, 2=1, 3=2, 4=3, 5=5, 6=8, 7=13, 8=21, 9=34, 10=55, 11=89, 12=144, 13=233, 14=377, 15=610, 16=987, 17=1597, 18=2584, 19=4181, 20=6765, 21=10946, 22=17711, 23=28657, 24=46368}
myMap = 31
memo 只有 25 个元素,但 size 返回 31。如何?这是哈希映射实现中的错误吗?
我将 hashmap 更改为 ConcurrentHashMap,如果我要求第 9 个或更多斐波那契数,它就会挂起。
但是即使是 1000 也可以正确返回 fibanocci 数!
【问题讨论】:
-
我在运行此代码时收到
java.util.ConcurrentModificationException。你在哪个 JDK 版本上运行? -
我也尝试了
ConcurrentHashMap,它抛出了一个特定的错误(java.lang.IllegalStateException: Recursive update),这表明你真的不应该这样做。 -
HashMap#computeIfAbsent 的 javadoc 对此有一个特殊警告:映射函数不应在计算期间修改此映射。
-
@Aomine 您可以通过循环轻松完成。甚至不需要递归。
-
@Aomine OP is 使用递归方法(方法
fibonacci调用自身两次),但尝试添加memoization 以提高性能。