我编写了函数的许多实现,以计算给定位置的斐波那契数。
斐波那契类:此类有助于我测试每个实现,而无需重写相同的测试代码。我不想在这里添加“ fibonacci(n - 2).add(fibonacci(n - 1));
”,因为某些实现不使用它(命令性迭代,功能性迭代)。
public interface Fibonacci {
BigInteger fibonacci(int n);
}
递归斐波那契类
public class SimpleRecursiveFibonacci implements Fibonacci{
public BigInteger fibonacci(int n) {
if(n < 2) {
return BigInteger.ONE;
}
return fibonacci(n - 2).add(fibonacci(n - 1));
}
}
和“记忆递归斐波那契”类
public class MemoizedRecursiveFibonacci implements Fibonacci{
private Map<Integer, BigInteger> cache = new HashMap<>();
public BigInteger fibonacci(int n) {
if(n < 2) {
return BigInteger.ONE;
}
if(!cache.containsKey(n)){
BigInteger currentFibonacci = fibonacci(n - 2).add(fibonacci(n - 1));
cache.put(n, currentFibonacci);
}
return cache.get(n);
}
}
如我所见,MemorizedRecursiveFibonacci类中有一些重复的代码
if(n < 2) {
return BigInteger.ONE;
和
BigInteger currentFibonacci = fibonacci(n - 2).add(fibonacci(n - 1));
如何使其保持干燥?删除重复的代码?
答案 0 :(得分:2)
MemorizedRecursiveFibonacci
可以委派给RecursiveFibonacci
实例:
public class MemoizedRecursiveFibonacci implements Fibonacci {
SimpleRecursiveFibonacci simple = new SimpleRecursiveFibonacci();
private Map<Integer, BigInteger> cache = new HashMap<>();
public BigInteger fibonacci(int n) {
if(!cache.containsKey(n)) {
BigInteger currentFibonacci = simple.fibonacci(n);
cache.put(n, currentFibonacci);
}
return cache.get(n);
}
}
或者,更优雅地使用Java 8的Map#computeIfAbsent
:
public class MemoizedRecursiveFibonacci implements Fibonacci {
SimpleRecursiveFibonacci simple = new SimpleRecursiveFibonacci();
private Map<Integer, BigInteger> cache = new HashMap<>();
public BigInteger fibonacci(int n) {
return cache.computeIfAbsent(n, k -> simple.fibonacci(k));
}
答案 1 :(得分:1)
抽象的公共父母呢? 像这样:
public abstract class ParentFibonacci implements Fibonacci {
protected BigInteger getFirstValues(int n) {
if (n < 2) {
return BigInteger.ONE;
}
return BigInteger.ZERO;
}
}
这样,您的Fibonacci实现需要实现Fibonacci.fibonacci(int n)并可以使用父方法。
public class SimpleRecursiveFibonacci extends ParentFibonacci {
public BigInteger fibonacci(int n) {
if (n < 2) {
return getFirstValues();
}
return fibonacci(n - 2).add(fibonacci(n - 1));
}
}