8. 求斐波那契数列的第n项
我也不解释了,这个提到了很多,直接上代码:
import java.math.BigInteger;
/**
* Class day08 ...
*
* @author LiJun
* Created on 2018/12/23
*/
// 求斐波那契数列的第n项
public class day08 {
// 递归实现,但是没意思,复杂了
public long Fibonacci(int n) {
if (n <= 0) {
return 0;
}
if (n == 1) {
return 1;
}
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
public long Fibonacci2(int n) {
if (n <= 0) {
return 0;
}
if (n == 1) {
return 1;
}
long a = 0;
long b = 1;
long result = 0;
for (int i = 2; i <= n; i++) {
result = a + b;
a = b;
b = result;
}
return result;
}
public BigInteger Fibonacci3(int n) {
if (n <= 0) {
return new BigInteger("0");
}
if (n == 1) {
return new BigInteger("1");
}
BigInteger a = new BigInteger("0");
BigInteger b = new BigInteger("1");
BigInteger result = new BigInteger("0");
for (int i = 2; i <= n; i++) {
result = a.add(b);
a = b;
b = result;
}
return result;
}
public static void main(String[] args) {
day08 day = new day08();
long start = System.currentTimeMillis();
System.out.println(day.Fibonacci(43));
long end = System.currentTimeMillis();
System.out.println("用时:" + (end - start));
/*代码实验 当递归到40以上 就已经很慢了*/
start = System.currentTimeMillis();
System.out.println(day.Fibonacci2(92));
end = System.currentTimeMillis();
System.out.println("用时:" + (end - start));
start = System.currentTimeMillis();
System.out.println(day.Fibonacci3(100));
end = System.currentTimeMillis();
System.out.println("用时:" + (end - start));
/*
理论上java的long可以存92的斐波那契数 -2^63~2^63-1
*/
/*
输出结果如下:
433494437
用时:3475
7540113804746346429
用时:0
354224848179261915075
用时:2
*/
}
}
事实上,递归虽然能很好的简化问题,但是当循环数达到一定值的时候,递归的效率上远远不如迭代。
接下来,我来分析下递归和迭代吧:
递归:
本质上就是在过程中自身调用自身,而且必须要有名曲的递归结束条件。在这个过程中会进行函数压栈操作,会浪费时间和空间。
迭代:
迭代是函数内某段代码实现循环。
理论上来说:任何递归都能转换成迭代,反之亦然,但是代价通常很高,递归的效率确实低。
从网上找了下别人的总结:
定义 | 优点 | 缺点 | |
---|---|---|---|
递归 | 程序调用自身的编程技巧称为递归 | 1)大问题化为小问题,可以极大的减少代码量;2)用有限的语句来定义对象的无限集合.;3)代码更简洁清晰,可读性更好 | 1)递归调用函数,浪费空间;2)递归太深容易造成堆栈的溢出; |
迭代 | 利用变量的原值推算出变量的一个新值,迭代就是A不停的调用B. | 1)迭代效率高,运行时间只因循环次数增加而增加;2)没什么额外开销,空间上也没有什么增加, | 1) 不容易理解;2) 代码不如递归简洁;3) 编写复杂问题时困难。 |
二者关系 | 1) 递归中一定有迭代,但是迭代中不一定有递归,大部分可以相互转换。2) 能用迭代的不用递归,递归调用函数,浪费空间,并且递归太深容易造成堆栈的溢出./相对/ |