【问题标题】:Memoization of recursive Fibonacci method not faster?递归斐波那契方法的记忆不是更快吗?
【发布时间】:2019-07-03 23:15:47
【问题描述】:

我尝试了一个递归斐波那契方法的记忆,它返回了正确的数字。但是,它并没有比以前更快。我假设这是因为我没有正确利用数组来跟踪,而且我仍在进行冗余调用。您能告诉我要更改什么以便我可以正常使用吗?

不确定是否重要,但fibIndex[]在全局区域中声明,并在获取输入后在main方法中设置为[index + 1]的长度。

public static BigInteger fibRec(int index)
{
    BigInteger results; 

    if (index <= 2)
    {
        results = BigInteger.ONE;
    }
    else
    {
        if (fibIndex[index] != null)
        {
            results = fibIndex[index];
        }
        else
        {
            results = fibRec(index - 1).add(fibRec(index - 2));

        }
    }
    return results;
}

【问题讨论】:

    标签: java recursion fibonacci biginteger memoization


    【解决方案1】:

    我注意到您实际上并没有在任何地方填写 fibIndex。基于此,你的 if 语句条件什么时候触发?

    这是否让您知道要解决什么问题?

    【讨论】:

    • 啊,这有助于我更好地理解其他评论。由于我没有填充数组,因此我的 if 语句无法正确触发,因为我总是得到一个空值。这就是 Leo Aso 所说的“检查从未被记忆的记忆结果”的意思。谢谢,非常感谢!
    【解决方案2】:

    它并没有运行得更快,因为您实际上没有使用记忆,即您没有将结果放入数组中。如果你不这样做,那么你的实现实际上会更慢,因为你一直在检查你从未真正记住的记忆结果。这是您需要做的。

    public static BigInteger fibRec(int index) { 
        if (index <= 2) return BigInteger.ONE;
    
        BigInteger result = fibIndex[index];
        if (result == null) {
            result = fibRec(index - 1).add(fibRec(index - 2));
            fibIndex[index] = result; // you forgot this
        }
        return result;
    }
    

    编辑:我之前在这里做了一个注释,关于您只调用一次的方法不需要记忆,但后来我记得该方法是递归的。所以忘记我之前在这里说的吧,记忆化实际上会大大加快方法的速度。

    【讨论】:

    • 天哪,我犯了一个多么简单的错误!太感谢了。我计算的数字越大,实际上花费的时间就越长。 50 之前需要 56 秒,现在是 0.003 秒!
    猜你喜欢
    • 2011-12-14
    • 2021-11-17
    • 2018-09-24
    • 2012-11-29
    • 2020-03-02
    • 2010-12-03
    • 2019-06-04
    • 2015-10-19
    相关资源
    最近更新 更多