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越大,两个算法相差越是天壤之别,不是一个数量级了,有了一个直接的感受之后,我们该选择那一个算法呢? 该如何评判一个算法好坏?