I have 2 class: RecursiveFibonacci and MemorizedRecursiveFibonacci. This is what I have so far.
RecursiveFibonacci Class
public class SimpleRecursiveFibonacci {
public BigInteger fibonacci(int n) {
if(n < 2) {
return BigInteger.ONE;
}
return fibonacci(n - 2).add(fibonacci(n - 1));
}
}
and MemorizedRecursiveFibonacci Class
public class MemoizedRecursiveFibonacci {
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);
}
}
As I see, there are some duplicated code in MemorizedRecursiveFibonacci Class
if(n < 2) {
return BigInteger.ONE;
and
BigInteger currentFibonacci = fibonacci(n - 2).add(fibonacci(n - 1));
How can I keep it DRY? remove duplicated code?
Maybe this is an option... but not the best i think.
public class SimpleRecursiveFibonacci {
public BigInteger fibonacci(int n) {
if(n < 2) {
return BigInteger.ONE;
}
return calculate(n);
}
protected BigInteger calculate(int n){
return fibonacci(n - 2).add(fibonacci(n - 1)),
}
}
public class MemoizedRecursiveFibonacci extends SimpleRecursiveFibonacci{
private Map<Integer, BigInteger> cache = new HashMap<>();
@Override
protected BigInteger calculate(int n) {
if(!cache.containsKey(n)){
BigInteger currentFibonacci = super.calculate(n);
cache.put(n, currentFibonacci);
}
return cache.get(n)
}
}
How about something like this:
public class SimpleRecursiveFibonacci {
/** Gets the fibonacci value for n */
public final BigInteger fibonacci(int n) {
if (n == 0) {
return BigInteger.ZERO;
} else if (n == 1) {
return BigInteger.ONE;
}
return getFibonacci(n);
}
/** Recursively calculates the fibonacci by adding the two previous fibonacci. */
protected final BigInteger calculateFibbonacci(int n) {
return fibonacci(n - 2).add(fibonacci(n - 1));
}
/**
* Somehow get the fibonacci value for n.
* Could be by calculation, getting it from a cache, or anything.
* Defaults to calculation.
*/
protected BigInteger getFibonacci(int n) {
return calculateFibbonacci(n);
}
}
public class MemoizedRecursiveFibonacci extends SimpleRecursiveFibonacci {
// Cache using an array list as recommended by user @DodgyCodeException
private ArrayList<BigInteger> cache = new ArrayList<>();
@Override
protected BigInteger getFibonacci(int n) {
if (cache.size() < n) {
BigInteger fib = calculateFibbonacci(n);
cache.add(fib);
return fib;
} else {
return cache.get(n - 1);
}
}
}
Another example using Java 8 features - BiFunction
interface with lambda expression:
BiFunction<Fibonacci, Integer, BigInteger> func = (fibonacci, n) -> {
if (n < 2) {
return BigInteger.ONE;
}
return fibonacci.calc(n - 2).add(fibonacci.calc(n - 1));
};
new CachedFibonacci(func).calc(100);
Implementation:
interface Fibonacci {
BigInteger calc(int n);
}
class SimpleFibonacci implements Fibonacci {
private BiFunction<Fibonacci, Integer, BigInteger> fibonacci;
SimpleFibonacci(BiFunction<Fibonacci, Integer, BigInteger> fibonacci) {
this.fibonacci = fibonacci;
}
public BigInteger calc(int n) {
return fibonacci.apply(this, n);
}
}
class CachedFibonacci implements Fibonacci {
private BiFunction<Fibonacci, Integer, BigInteger> fibonacci;
private Map<Integer, BigInteger> cache = new HashMap<>();
CachedFibonacci(BiFunction<Fibonacci, Integer, BigInteger> fibonacci) {
this.fibonacci = fibonacci;
}
public BigInteger calc(int n) {
if (!cache.containsKey(n)) {
cache.put(n, fibonacci.apply(this, n));
}
return cache.get(n);
}
}
use static method:
public class SimpleRecursiveFibonacci {
public static BigInteger fibonacci(int n) {
if(n < 2) {
return BigInteger.ONE;
}
return fibonacci(n - 2).add(fibonacci(n - 1));
}
}
public class MemoizedRecursiveFibonacci {
private Map<Integer, BigInteger> cache = new HashMap<>();
public BigInteger fibonacci(int n) {
if(!cache.containsKey(n)){
BigInteger currentFibonacci = SimpleRecursiveFibonacci.fibonacci(n);
cache.put(n, currentFibonacci);
}
return cache.get(n);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.