【发布时间】:2014-05-03 11:46:21
【问题描述】:
我正在尝试创建阶乘函数的记忆版本。当我调用 factMemoized(4) 时,它第一次计算 4 的阶乘并将其存储在 Map 中。当我再次调用 factMemoized(4) 时,它现在给出了存储的结果,而不是再次重新计算它。这按预期工作。但是,当我调用 factMemoized(3) 时,它会重新计算值,尽管它已经计算了 fact(3) 作为计算 fact(4) 的一部分。有什么方法可以确保即使是作为递归调用的一部分计算的值也将存储在 map 中,而无需在 fact() 函数中添加 memoization 函数?
import java.util.HashMap;
import java.util.Map;
public class MemoizeBetter {
public static <F, T> Function<F, T> memoize(final Function<F, T> inputFunction) {
return new Function<F, T>() {
// Holds previous results
Map<F, T> memoization = new HashMap<F, T>();
@Override
public T apply(final F input) {
// Check for previous results
if (!memoization.containsKey(input)) {
// None exists, so compute and store a new one
memoization.put(input, inputFunction.apply(input));
}else{
System.out.println("Cache hit:"+input);
}
// At this point a result is guaranteed in the memoization
return memoization.get(input);
}
};
}
public static void main(String args[]){
final Function<Integer, Integer> fact = new Function<Integer, Integer>() {
@Override
public Integer apply(final Integer input) {
System.out.println("Fact: " + input);
if(input == 1)
return 1;
else return input * apply(input -1);
}
};
final Function<Integer, Integer> factMemoized = MemoizeBetter.memoize(fact);
System.out.println("Result:"+ factMemoized.apply(1));
System.out.println("Result:"+factMemoized.apply(2));
System.out.println("Result:"+factMemoized.apply(3));
System.out.println("Result:"+factMemoized.apply(2));
System.out.println("Result:"+factMemoized.apply(4));
System.out.println("Result:"+factMemoized.apply(1)); }
}
interface Function<F,T>{
T apply(F input);
}
【问题讨论】:
-
memorize map 被覆盖,即 (0,4),它将覆盖到相同的索引 (0,3),确保您的逻辑正确。
标签: java memoization