为什么这样写显著提升了Fibonacci sequence性能??

发布于 2022-09-01 15:39:03 字数 2162 浏览 12 评论 0

问题来自Algorithms(算法,第四版)的1.1.19练习题。
题目如下:

在计算机上运行一下程序:

Javapublic class Fibonacci {
    public static long F(int N)  {
        if (N == 0)
            return 0;
        if (N == 1) 
            return 1;
        return F(N-1) + F(N-2);
    }
    public static void main(String[] args)  {
        for (int N = 0; N < 100; N++)
            StdOut.println(N + " " + F(N));
    }
}

计算机用这段程序在一小时内能得到的F(N)结果的最大N值是多少?开发F(N)的一个更好的实现,用数组保存已经计算的值。

---------题目结束--------------

首先我在计算机上(windows8.1 64位系统)运行上面程序,如下:
f1

发现用上面题目给出的方法运行到N = 40多时,程序已经明显慢下来了,

问题1:慢下来是因为处理的数据太大了,而且每次都要再次计算?还是因为其他什么原因?
问题2:题目中要预测计算机在一小时内能够得到F(N)结果的最大N值,这个怎么做?

然后在这里提供了题目问题的代码,如下:

javapublic class Ex_1_1_19
{
    public static long F(int N)
    {
        if (N == 0) return 0;
        if (N == 1) return 1;
        return F(N-1) + F(N-2);
    }

    public static long Fib(int N)
    {
        long[] f = new long[N+1];
        return Fib(N, f);
    }

    public static long Fib(int N, long[] f)
    {
        if (f[N] == 0)
        {
            if (N == 1)
                f[N] = 1;
            else if (N > 1)
                f[N] = Fib(N-1, f) + Fib(N-2, f);
        }

        return f[N];
    }

    public static void main(String[] args)
    {
//        for (int N = 0; N < 100; N++)
//            StdOut.println(N + " " + F(N));
        for (int N = 0; N < 100; N++)
            StdOut.println(N + " " + Fib(N));
    }
}

再次运行时,居然在1秒多就运行完了:

图片描述

问题3:
很好奇为什么这么快,自己尝试分析下,用N=0,1,2,3试,但是在Fib函数中为什么要if (f[N] == 0)呢?数组最后一个元素为0?
是因为用数组 f 保存已经计算过的值了,所以不需要再重新计算了所以才快了很多吗?
问题4:
最后结果从93行开始,93,95,96,97,99行出现的负数,大致知道是和操作系统运算有关,但又不是很清楚,求解释?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

断念 2022-09-08 15:39:03

问题1就是保存了中间结果
问题2我也不肯定,我猜这个运算时间也是斐波那契数列
问题3的f(N)==0是用来判断这个值有没有计算过的,计算过直接调用已保存的结果,没计算过的f(N)是0,就进行if立面的计算
问题4是long长度越界了

小巷里的女流氓 2022-09-08 15:39:03

保存中间计算结果,避免重复计算

自我难过 2022-09-08 15:39:03

你可以上网去查查尾递归的概念,这个其实就是编译器的优化而已。
http://www.cnblogs.com/JeffreyZhao/archive/2009/04/01/tail-recursion-e...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文