使用Java中的memoization进行Fibonacci计算

时间:2018-01-26 13:37:53

标签: java arrays

我尝试下面的代码狙击,而我正在初始化 mem [] 数组,它采取 1ms 来执行代码,但如果我在里面初始化它执行 ~16000 ms的方法。我无法理解,为什么?,请帮助我。

public class FiboMemoization {
    //public static long [] mem = new long[41];
    public static long fibo(int n){
    //  long [] mem = new long[41];
        if(mem[n] == 0){
            if(n <= 1){
                mem[n] = n; 
            }else if(mem[n] != 0)
                mem[n] = mem[n];
            else
                mem[n] = fibo(n-1)+fibo(n-2);
        }
        return mem[n];
    }
}   

3 个答案:

答案 0 :(得分:1)

如果内存(即long[] mem)存储在 函数中,则只记忆它。

函数内的

long[] mem会导致两个问题:

  1. 每次通话重新分配内存(慢)
  2. 不进行memoization,因为每次调用函数时数组都是空的(Java中的新数组为0)

答案 1 :(得分:0)

在方法mem中初始化fibo数组时执行需要更长的时间,因为每次递归调用此方法时,每次调用都会初始化mem数组。

mem方法之外初始化fibo数组时,它只会被初始化一次,因此方法会在更短的时间内执行。

答案 2 :(得分:0)

import java.math.BigInteger;
import java.util.Arrays;

public class Main {


    private static int _memo_length;
    private static int _memo_idx;
    private static BigInteger[] _memo;

    static {
        _memo_length = 1024;
        _memo = new BigInteger[_memo_length];
        _memo[0] = BigInteger.ONE;
        _memo[1] = BigInteger.ONE;
        _memo_idx = 1;
    }


    public static void main(String[] args) {
        int xIndex = 4000; //locate the 4000th fibo member.

        BigInteger output = locateFibonacciMember(xIndex - 1);

        System.out.println(output);
    }

    public static BigInteger locateFibonacciMember(int idx) {
        if (idx <= _memo_idx) {
            return _memo[idx];
        }
        while (idx > _memo_idx) {
            if (++_memo_idx >= _memo.length) {
                if (!_extendMemo()) return BigInteger.ZERO;
            }
            _memo[_memo_idx] = _memo[_memo_idx - 1].add(_memo[_memo_idx - 2]);
        }
        return _memo[_memo_idx];
    }

    private static boolean _extendMemo() {
        try {
            _memo = Arrays.copyOf(_memo, _memo.length + _memo_length);
        } catch (Exception e) {
            return false;
        }
        return true;
    }
}