【问题标题】:Creating memorization algorithm given a fibonacci recursive function给定斐波那契递归函数创建记忆算法
【发布时间】:2020-03-02 14:26:55
【问题描述】:

对于学校作业,我们必须创建一个记忆的fibonacci 函数,该函数重用计算fibonacci 的递归实现。

有什么好的方法来设计我们的记忆函数,以利用现有的函数?到目前为止,这是我的实现:

基类:

    public int computeFibonacci(int position) {
        assertPosition(position);

        if (position < 2) {
            return 1;
        }
        return computeFibonacci(position - 1) + computeFibonacci(position - 2);
    }

继承类:

    public int computeFibonacci(int position) {
        assertPosition(position);

        if (position < 2) {
            return 1;
        }

        if (this.memoizedList.containsKey(position)) {
            return this.memoizedList.get(position);
        }
        int result = super.computeFibonacci(position - 1) + super.computeFibonacci(position - 2);
        this.memoizedList.put(position, result);
        return result;
    }

【问题讨论】:

  • 您想阅读这篇文章以获得最佳解决方案 - geeksforgeeks.org/…
  • 你不需要调用super实现。如果您调用super 实现,那么您将无法使用记忆值。

标签: java recursion fibonacci memoization


【解决方案1】:

在基类中重用递归实现存在混淆。 如果调用递归实现,它会递归计算fib(n) = fib(n-1) + fib(n-2) = ...,这与memo函数冲突。备忘录功能试图节省计算时间。 备忘:

public int computeFibonacci(int position) {
        assertPosition(position);

        if (position < 2) {
            return 1;
        }

        if (this.memoizedList.containsKey(position)) {
            return this.memoizedList.get(position);
        }
        int result = computeFibonacci(position - 1) + computeFibonacci(position - 2);
        this.memoizedList.put(position, result);
        return result;
    }

例如,您尝试打印斐波那契的前 1000 个元素,备忘录功能将节省计算的时间。

【讨论】:

    【解决方案2】:

    您的子类版本没有充分利用缓存值。例如,如果您调用computeFibonacci(5),而memoizedList 不包含该键,您将调用super.computeFibonacci(4)super.computeFibonacci(3),即使它们已经被缓存。相反,您应该致电super.computeFibonacci(5)

    public int computeFibonacci(int position) {
        assertPosition(position);
    
        if (position < 2) {
            return 1;
        }
    
        if (this.memoizedList.containsKey(position)) {
            return this.memoizedList.get(position);
        } else {
            int result = super.computeFibonacci(position);
            this.memoizedList.put(position, result);
            return result;
        }
    }
    

    【讨论】:

    • 请注意,此函数不会重新实现原始的computeFibonacci。如果重新实现原来的功能是多余的。
    • @JoopEggen 我不确定你的意思。我对子类的computeFibonacci 的建议是获取存储在缓存中的值(如果可用),否则调用超类实现。
    • 哦,这在某种程度上是一种赞美,因为 OP 重复了原始方法的实现。您的答案是记忆的一般解决方案的一半。
    猜你喜欢
    • 2021-11-17
    • 2011-12-14
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 2021-05-21
    • 1970-01-01
    • 2021-12-01
    • 2019-07-03
    相关资源
    最近更新 更多