从“斐波拉契数”开始接触算法

179 阅读1分钟

Pascal 之父 Nicklaus Wirth 曾说: 算法 + 数据结构 = 程序

算法又是什么? 我们把 算法 看做是用于 解决特定问题的 一系列 执行步骤。

比如: 求第 n 个斐波拉契数。 我们该如何 求呢?

不同的人,可以想出相同的办法,或者不同的办法,"条条大路通罗马"。哪一种是最好的?使用不同的算法,解决相同的问题,效率一样吗? 有没有差别?

算法1:

public static int fib(int n) {
    if (n <= 1) return n;
    return fib(n-1) + fib(n-2);
}

算法2:

public static int fib2(int n) {
    if (n <= 1) return n;
    int first = 0;
    int second = 1;
    for (int i = 0; i < n-1; i++) {
        int sum = first + second;
        first = second;
        second = sum;
    }
    return second;
}

测试一下哪两个算法:

public static void main(String[] args) {
    int n = 45;
//		System.out.println(fib(77));
//		System.out.println(fib2(77));
    Times.test("fib1", new Task() {
        @Override
        public void execute() {
            // TODO Auto-generated method stub
            System.out.println(fib(n));

        }
    });
    
    Times.test("fib2", new Task() {
        @Override
        public void execute() {
            // TODO Auto-generated method stub
            System.out.println(fib2(n));

        }
    });
}

执行结果:

【fib1】
开始:23:43:56.606
1134903170
结束:23:44:03.197
耗时:6.59秒
-------------------------------------
【fib2】
开始:23:44:03.200
1134903170
结束:23:44:03.200
耗时:0.0秒
-------------------------------------

附上:测试方法耗时的工具类:

import java.text.SimpleDateFormat;
import java.util.Date;

public class Times {
	private static final SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss.SSS");
	
	public interface Task {
		void execute();
	}
	
	public static void test(String title, Task task) {
		if (task == null) return;
		title = (title == null) ? "" : ("【" + title + "】");
		System.out.println(title);
		System.out.println("开始:" + fmt.format(new Date()));
		long begin = System.currentTimeMillis();
		task.execute();
		long end = System.currentTimeMillis();
		System.out.println("结束:" + fmt.format(new Date()));
		double delta = (end - begin) / 1000.0;
		System.out.println("耗时:" + delta + "秒");
		System.out.println("-------------------------------------");
	}
}

我们发现从执行耗时上来看,n越大,两个算法相差越是天壤之别,不是一个数量级了,有了一个直接的感受之后,我们该选择那一个算法呢? 该如何评判一个算法好坏?