斐波纳契数列(递归)、Scanner类

一、简单的费波纳切数列

 1 public class FbDemo01 {
 2 
 3     public static void main(String[] args) {
 4         for(int i=1;i<5;i++){
 5             int j = Fbi(i);
 6             System.out.println(j);
 7         }
 8     }
 9 
10     private static int Fbi(int i) {
11         if(i<2){
12             return i == 0 ? 0 : 1;    
13         }
14         int a = Fbi(i-1) + Fbi(i-2);
15         return a ;
16     }
17 }

二、Scanner类结合费波纳切数列

在Scanner类中提供了一个可以接收InputStream类型的构造方法,这就表示只要是字节输入流的子类都可以通过Scanner类进行方便的读取。

Scanner类是用于扫描输入文本的。

可以使用该类创建一个对象:Scanner reader=new Scanner(System.in);

然后reader调用下面的方法,读取用户在命令行输入的各种类型的数据

int nextInt();      //将输入信息的下一个标记扫描为一个 int
double nextDouble(); //将输入信息的下一个标记扫描为一个double
...
String nextNext();  //查找并返回来自此扫描器的下一个完整标记(字符串)
String nextLine();  //此扫描器执行当前行,并返回跳过的输入信息
...
boolean hasNext();  //如果此扫描器的输入中有另一个标记,则返回true
boolean hasNext(Pattern pattern); //如果下一个完整标记与指定模式匹配,则
                                   返回true
boolean hasNext(String pattern); //如果下一个标记与从指定字符串构造的模式
                                   匹配,则返回true
boolean hasNextInt(); //如果通过使用nextInt()方法,此扫描器输入信息中的下
                   一个标记可以解释为指定基数中的一个int 值,则返回true。
 1 import java.util.*;
 2 import java.io.*;
 3 public class fibonacci {
 4      public static int k=0;
 5         public static void main(String[] args) {
 6             Scanner cin=new Scanner(System.in); //Scanner类这是一个用于扫描输入文本的
 7             long a=cin.nextLong();                //将输入信息的下一个标记扫描为一个long
 8             System.out.println(fibonacci(a));
 9             System.out.println("共调用了"+k+"次");
10         }
11         public static long fibonacci(long m){
12             if(m==0|m==1){
13                 k++;
14                 return m;
15             }else{
16                 return fibonacci(m-1)+fibonacci(m-2);
17             }
18         }
19 }

三、 递归的缺点:

会造成调用栈的溢出,因为需要为每一次函数调用在内存栈中分配空间,而每个进程的栈的容量是有限的。当递归调用层级太多时,就会超出栈的容量,从而导致调用栈溢出。

同时,斐波纳契数类的特点:前面相邻两项的和,构成了后一项。

利用次特点,可以改进上面的程序,避免栈的溢出:

 1 package test02;
 2 
 3 import java.util.Scanner;
 4 
 5 public class Fibonacci {
 6     public static void main(String[] args) {
 7         Scanner cin=new Scanner(System.in); //Scanner类这是一个用于扫描输入文本的
 8         int a=cin.nextInt();                //将输入信息的下一个标记扫描为一个long
 9         System.out.println(Fibonacci(a));
10         
11     }
12 
13     public static int Fibonacci(int n) {
14         if(n==0){
15             return 0;
16         }
17         if(n==1){
18             return 1;
19         }
20         int numfn1=0;
21         int numfn2=1;
22         int currentfn=0;
23         for(int i=2;i<=n;i++){
24             currentfn=numfn1+numfn2;
25             numfn1=numfn2;
26             numfn2=currentfn;
27         }
28         return currentfn;
29     }
30 }

四、青蛙跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

思路:当前台阶的跳法总数=当前台阶后退一阶的台阶的跳法总数+当前台阶后退二阶的台阶的跳法总数。

 1 package test02;
 2 
 3 import java.util.Scanner;
 4 
 5 public class JumpFloorDemo {
 6 
 7     public static void main(String[] args) {
 8         Scanner cin=new Scanner(System.in); //Scanner类这是一个用于扫描输入文本的
 9         int a=cin.nextInt();                //将输入信息的下一个标记扫描为一个long
10         System.out.println(Fibonacci(a));
11     }
12 
13     private static int Fibonacci(int a) {
14         if(a==2||a==1){
15             return a;
16         }
17         // 第一阶和第二阶考虑过了,初始当前台阶为第三阶,向后迭代
18   
19         // 思路:当前台阶的跳法总数=当前台阶后退一阶的台阶的跳法总数+当前台阶后退二阶的台阶的跳法总数
20         int currentjumpSum=0;//当前台阶的跳法总数
21         int jumpSumBackStep1=2;//当前台阶后退一阶的台阶的跳法总数
22         int jumpSumBackStep2=1;//当前台阶后退二阶的台阶的跳法总数
23         for(int i=3;i<=a;i++){
24             currentjumpSum=jumpSumBackStep1+jumpSumBackStep2;
25             jumpSumBackStep2=jumpSumBackStep1;// 后退一阶在下一次迭代变为后退两阶
26             jumpSumBackStep1=currentjumpSum;// 当前台阶在下一次迭代变为后退一阶
27         }
28         return currentjumpSum;
29     }
30 
31 }

五、矩阵覆盖

用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

有以下几种情形:

(1) target <= 0 大矩形为<= 2*0,直接return 1;
(2) target = 1大矩形为2*1,只有一种摆放方法,return1;
(3) target = 2 大矩形为2*2,有两种摆放方法,return2;
(4) target = n 分为两步考虑:
        第一次摆放一块 2*1 的小矩阵,则摆放方法总共为f(target - 1)

第一次摆放一块1*2的小矩阵,则摆放方法总共为f(target-2)

因为,摆放了一块1*2的小矩阵(用√√表示),对应下方的1*2(用××表示)摆放方法就确定了,所以为f(targte-2)
 1 package test02;
 2 
 3 import java.util.Scanner;
 4 
 5 public class RectCover {
 6     public static void main(String[] args) {
 7         Scanner cin=new Scanner(System.in); //Scanner类这是一个用于扫描输入文本的
 8         int a=cin.nextInt();                //将输入信息的下一个标记扫描为一个long
 9         System.out.println(Fibonacci(a));
10     }
11 
12     private static int Fibonacci(int a) {
13         if (a < 1) {
14             return 0;
15         } else if (a == 1 || a == 2) {
16             return a;
17         } else {
18             return Fibonacci(a-1) + Fibonacci(a-2);
19         }
20     }
21 }

 

posted @ 2017-08-09 20:28  XuGuobao  阅读(322)  评论(0编辑  收藏  举报