package net.liuyx.algorithm;
public class Fibonacci {
private static int[][] a = { { 1, 1 }, { 1, 0 } };
/**
* @param args
*/
public static void main(String[] args) {
for (Tester test : tests)
test.test(80);
}
private static Tester[] tests = {/* new Tester("常规递归") {
@Override
long fib(int n) {
if (n < 2)
return n;
return fib(n - 1) + fib(n - 2);
}
}, */new Tester("尾递归") {
@Override
long fib(int n) {
return fib2(n, 1, 1);
}
private long fib2(int n, int acc1, int acc2) {
if (n < 2)
return acc1;
return fib2(n - 1, acc2, acc1 + acc2);
}
}, new Tester("尾递归转换成循环性") {
@Override
long fib(int n) {
int acc1 = 0, acc2 = 1;
while (true) {
if (n == 0) {
return acc1;
}
if (n == 1)
return acc2;
int tmp = acc1;
acc1 = acc2;
acc2 = acc2 + tmp;
n--;
}
}
}, new Tester("经过算法优化的 ") {
@Override
long fib(int n) {
int[][] arr = fibonacciAlogrithm(n);
long result = arr[1][1];
return result;
}
private int[][] fibonacciAlogrithm(int n) {
int[][] result = { { 1, 1 }, { 1, 0 } };
while (n != 0) {
if ((n & 1) != 0) {
result = multiply(result, a);
}
a = multiply(a, a);
n = n >> 1;
}
return result;
}
private int[][] multiply(int[][] a, int[][] b) {
int[][] result = new int[2][2];
result[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0];
result[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1];
result[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0];
result[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1];
return result;
}
} };
private static abstract class Tester {
private String name;
public Tester(String name) {
this.name = name;
}
public void test(int n) {
System.out.print(name + ": ");
long start = System.nanoTime();
fib(n);
long duration = System.nanoTime() - start;
System.out.println("历时: " + duration);
}
abstract long fib(int n);
}
}
结果: