一、问题
下面用了6种方法打印斐波那契数列的前50项:
1、普通方法
2、数组方法
3、集合方法
4、递归方法
5、Map方法
6、BigDecimal方法
二、源码
结合网上的方法,再加上同事同学提供的建议,加上自己的研究,源代码如下:
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class fibonacciTest {
public static void main(String[] args) {
int length=1000;
long t1=System.currentTimeMillis();
//1、普通打印
fibonacciOrdinary(length);
long t2=System.currentTimeMillis();
//2、数组打印
fibonacciMethodOfArray(length);
long t3=System.currentTimeMillis();
//3、集合打印
fibonacciMethodOfList(length);
long t4=System.currentTimeMillis();
//4、递归打印
//fibonacciMethodOfRecursive(length);
long t5=System.currentTimeMillis();
//5、Map打印
fibonacciMethodOfMap(length);
long t6=System.currentTimeMillis();
//6、测试
fibonacciMethodOfBigDecimal(length);
long t7= System.currentTimeMillis();
System.out.println("普通方法耗时:"+(t2-t1)+"ms");
System.out.println("数组方法耗时:"+(t3-t2)+"ms");
System.out.println("集合方法耗时:"+(t4-t3)+"ms");
System.out.println("递归方法耗时:"+(t5-t4)+"ms");
System.out.println("Map方法耗时:"+(t6-t5)+"ms");
System.out.println("BigDecimal方法耗时:"+(t7-t6)+"ms");
}
/****************************************************/
//普通
private static void fibonacciOrdinary(int length){
double a = 1, b = 1, c = 2;
System.out.println("【普通方法】斐波那契数列前"+length+"项为:");
System.out.println("第"+1+"项:"+a);
System.out.println("第"+2+"项:"+b);
//因为前面还有两个1、1 所以i<=18
for (int i = 1; i < length; i++) {
c = a + b;
a = b;
b = c;
System.out.println("第"+(i+1)+"项:"+c);
}
}
/***************************************************/
//数组,有问题
private static void fibonacciMethodOfArray(int length){
double array [] = new double[length];
array[0] = 1.0;
array[1] = 1.0;
for (int i=2;i<length;i++){
array[i]=array[i-1]+array[i-2];
}
System.out.println("【数组方法】斐波那契数列前"+length+"项如下所示:");
for (int i=0;i<length;i++){
System.out.println("第"+(i+1)+"项:"+array[i]);
}
}
/************************************************/
//集合
private static void fibonacciMethodOfList(int length){
List<Double> longList = new ArrayList<>();
longList.add(1.0);
longList.add(1.0);
System.out.println("【集合方法】斐波那契数列前"+length+"项如下:");
for (int i=2;i<length;i++){
longList.add(longList.get(i-1)+longList.get(i-2));
}
for (int i=0;i<length;i++){
System.out.println("第"+(i+1)+"项的值为:"+longList.get(i));
}
}
/************************************************/
//递归;效率明显偏低
private static void fibonacciMethodOfRecursive (long length){
System.out.println("【递归方法】斐波那契数列的前"+length+"项为:");
for (int j = 1; j <= length; j++) {
System.out.println("第"+j+"项:"+getFibonacci(j));
}
}
private static int getFibonacci(int i) {
if (i == 1 || i == 2)
return 1;
else
return getFibonacci(i - 1) + getFibonacci(i - 2);
}
/************************************/
//Map
private static void fibonacciMethodOfMap(int length){
System.out.println("【Map方法】斐波那契数列的前"+length+"项为:");
Map<Integer,String> array = new HashMap<>(1000,1f);
array.put(0, "1");
array.put(1, "1");
array.put(2, "2");
for (int i=3;i<=length;i++){
BigDecimal decimal1 = new BigDecimal(array.get(i-1));
BigDecimal decimal2 = new BigDecimal(array.get(i-2));
array.put(i, decimal1.add(decimal2).toString());
}
for (int i=0;i<length;i++){
System.out.println("第"+(i+1)+"项:"+array.get(i));
}
}
/************************************/
//测试
private static void fibonacciMethodOfBigDecimal(int length){
System.out.println("【BigDecimal方法】斐波那契数列的前"+length+"项为:");
BigDecimal decimal1 = new BigDecimal(1);
BigDecimal decimal2 = new BigDecimal(1);
BigDecimal decimal;
for (int i=2;i<=length;i++){
if (i==1){
System.out.println("第1项"+decimal1);
}else if (i==2){
System.out.println("第2项"+decimal2);
}else {
decimal=decimal2.add(decimal1);
decimal1=decimal2;
decimal2=decimal;
System.out.println("第"+i+"项"+decimal);
}
}
}
}
三、结果
打印斐波那契前1000个数结果如下:
普通方法耗时:243ms
数组方法耗时:162ms
集合方法耗时:80ms
//递归方法耗时:0ms
Map方法耗时:293ms
BigDecimal方法耗时:97ms
四、分析
4.1、【效率性】从效率上看,数组,集合,BigDecimal方法较为快速;但是这里有个不确定因素就是机器性能是不是平均的,并且打印耗时也是很严重的,所以上面的结果仅供参考;集合等方法虽然快,但是不适合大数字的计算;递归方法太慢,是不合适的;
4.2、【正确性】
普通方法,数组方法,集合方法不能高位数计算; 而Map方法,BigDecimal方法均使用了BigDecimal,所以可以高位数计算; 而BigDecimal又剥离了Map外衣,所以大数据量建议用后两种方法;
//BigDecimal方法
private static void fibonacciMethodOfBigDecimal(int length){
System.out.println("【BigDecimal方法】斐波那契数列的前"+length+"项为:");
BigDecimal decimal1 = new BigDecimal(1);
BigDecimal decimal2 = new BigDecimal(1);
BigDecimal decimal;
for (int i=2;i<=length;i++){
if (i==1){
System.out.println("第1项"+decimal1);
}else if (i==2){
System.out.println("第2项"+decimal2);
}else {
decimal=decimal2.add(decimal1);
decimal1=decimal2;
decimal2=decimal;
System.out.println("第"+i+"项"+decimal);
}
}
}