我有一个记忆式递归函数来计算斐波那契数。我有此功能的测试用例。基本上,它发送一个位置,如果该位置已经有一个数字,则将其返回,如果没有,则进行计算。我通过调试器运行了代码,并意识到:
if (dictionary[position] != null){
result = dictionary[position];
}
从未被击中。完整代码如下。例如,如果您有calculatefib(4),它将要求fib(3)
,要求fib(2)
,要求fib(1)
,要求fib(0)
,以及何时堆栈开始关闭,永远不会保存值。因此,例如fib(2)
或更确切地说dictionary(2)
始终为null。它在调试器中的令人困惑的原因是它显示了计算出的值,但是当堆栈开始关闭时,它们又再次为空。我如何重构代码,使行始终被点击。
public BigInteger calculateFib(int position) {
final BigInteger[] dictionary = new BigInteger[100000];
BigInteger result = BigInteger.ONE;
if (position < 2) {
return result;
}
else {
if (dictionary[position] != null){
result = dictionary[position];
}
else {
result = calculateFib(position - 1).add(calculateFib(position - 2));
dictionary[position] = result;
}
return result
答案 0 :(得分:0)
每次您致电calculateFib()
此行:
final BigInteger[] dictionary = new BigInteger[100000];
创建数组dictionary[]
的临时实例
calculateFib()
完成后,dictionary[]
被销毁。
如果要在其中存储值并重用它,则必须在calculateFib()
之外的类级别上声明它。
编辑,这是我对您的逻辑的看法:
final BigInteger[] dictionary = new BigInteger[100000];
public BigInteger calculateFib(int position) {
if (position < 0)
return BigInteger.ZERO;
BigInteger result = BigInteger.ONE;
if (dictionary[position] != null) {
result = dictionary[position];
} else if (position < 2) {
dictionary[position] = result;
} else {
result = calculateFib(position - 1).add(calculateFib(position - 2));
dictionary[position] = result;
}
return result;
}
答案 1 :(得分:0)
您应该在方法外部声明备忘录存储,因为它必须记住方法调用之间的内容。现在,您正在为每个方法调用创建一个新的“ memo”存储字典,因此您永远不会记住任何东西。
将此方法带到类实例之外:
final BigInteger[] dictionary = new BigInteger[100000];
像
class MyClass {
final BigInteger[] dictionary = new BigInteger[100000];
public BigInteger calculateFib(int position) {
BigInteger result = BigInteger.ONE;
if (position < 2) {
return result;
}
else {
if (dictionary[position] != null){
result = dictionary[position];
}
else {
result = calculateFib(position - 1).add(calculateFib(position - 2));
dictionary[position] = result;
}
return result
}
}
}
答案 2 :(得分:0)
memoize
不会达到您期望的结果。
每次调用方法都需要初始化一个新字典,该字典将在该方法完成时终止。
您需要提取字典变量并将其初始化为方法之外。
final BigInteger[] dictionary = new BigInteger[100000];
答案 3 :(得分:0)