Fibonacci的幾種方法討論
阿新 • • 發佈:2018-12-09
1.用定義的遞迴演算法
f(n)=f(n-1)+f(n-2)
指數級別,因為不斷的重複計算,很多冗餘
public static int Fibonacci1(int n)
{ if (n<=1) return n;
return Fibonacci1(n-1)+Fibonacci1(n-2);
}
2.用定義的迭代演算法
線性,技巧是存下來,和動態規劃的思想有些一致。
public static int Fibonacci2(int n)
{ int a=0;int b=1;
if (n==0) return 0;
while(n>1)
{
int c=a;
a=b;
b=c+b;
n--;
}
return b;
}
3.公式法
f(n)為Φ^n/√5取最近的整數,Φ=(1+√5)/2.
這種方法必須注意精度
用double來計算時會發現n=37時答案已經不準了
public static int Fibonacci3(int n)
{ double a=(1+Math.sqrt(5))/2;
int m=(int)(Math.pow(a, n)/Math.sqrt(5));
if((n&1)==1) m++;//當n為奇數時,是取整加一
return m;
}
這種方法效率取決於指數的計算。如果是直接相乘是線性的,如果用減半的方法,可以得到對數級別的。
4.使用某個等式
對數級別的
//矩陣乘法 兩個方陣a、b乘積
public static int[][]Matrix_Multiply(int a[][],int b[][],int n)
{int c[][]=new int[n][n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
c[i][j]+=a[i][k]*b[k][j];
return c;
}
//矩陣快速冪(log n)
public static int Fibonacci4(int n)
{ int multi[][]= {{1,0},{0,1}};//單位矩陣
int x[][]= {{0,1},{1,1}};
while(n>0)
{
if((n&1)==1)
multi=Matrix_Multiply(multi,x,2);
x=Matrix_Multiply(x,x,2);
n>>=1;//相當於n=n/2
}
return multi[0][1];
}