题目一:古典问题:有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

A.普通方法: 保证a一直小于b(当n>=3时)

1.核心代码

while(true){
     if(n==1||n==2){
        System.out.println("第"+n+"个月兔子总数为:"+sum+"对");
        flag=true;
     }else if(n>=3){
        //相加次数为n-2次
        for (int i =n-2; i>0; i--) {
       //保证每次a都会小于b
             sum=a+b;
             a=b;
             b=sum;
             //测试语句:System.out.println("a的值为:"+a+",b的值为:"+b);
         }
       System.out.println("第"+n+"个月兔子总数为:"+sum+"对");
       flag=true;  
       }else{
             flag=false;
             System.out.println("输入n的值有误,请检查后重新输入");
             System.out.println("请再次输入n的值");
             n=scanner.nextInt();
       }
       if(flag){
             break;
       }
}

2.常见问题点分析

2.1 如何保证每次a<b(当n>=3)???

解决方案: 建立一个sum变量用来接收每月的兔子总数,

​ 每次接收完后,b会把原来的b值传给a

​ 然后b就就接收sum的值

2.2 布尔类型变量flag的作用是什么???

解答:flag默认初始值为true

​ a.当输入的n不符合条件时,flag值变为false

​ 此时无法使用break关键字跳出循环

​ 随后界面提示重新输入n的值

​ b.当输入的n符合条件时,flag值不变

​ 得到兔子总数sum后

​ 可以使用break跳出循环

​ c.对于a情况,再次输入一个正确的n值

​ 会得到兔子总数且跳出循环

2.3 内层循环次数(相加次数)为多少???

​ 解答如下所示:
当n=3,1+1=2,需要相加1次

当n=4时 1+1=2,1+2=3;需要相加2次

当n=5时 1+1=2,1+2=3,2+3=5;需要相加3次
​因而需要相加次数=n-2

3.运行截图

3.1 首次输入有误且n=1

在这里插入图片描述

3.2 首次输入有误且n=2

在这里插入图片描述

3.3 首次输入有误且n=5

在这里插入图片描述

3.4 首次输入正确且n=8

在这里插入图片描述

4.源代码

import java.util.Scanner;
public class TestRabbit01 {
    public static void main(String[] args) {
        System.out.println("题目:古典问题:有一对兔子,从出生后第 3 个月起每个月都生一对兔子\n小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问n个月的兔子总数为多少?");
        //前提条件: 第一个月时,兔子总数为1对,第二个月时,兔子总数为1对
        int a=1,b=1;
        System.out.println("请输入n的值:");
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        boolean flag=true;
        //用来判断是否跳出循环,默认为true
        // 当n输入有误时,flag=false,此时不会跳出循环
        int sum=1;
        //保存每月兔子总数
        while(true){
            if(n==1||n==2){
                flag=true;
                System.out.println("第"+n+"个月兔子总数为:"+sum+"对");
            }else if(n>=3){
                //相加次数为n-2次
                for (int i =n-2; i>0; i--) {
                   //保证每次a都会小于b
                   sum=a+b;
                   a=b;
                   b=sum;
                   //System.out.println("a的值为:"+a+",b的值为:"+b);
                }
                flag=true;
                System.out.println("第"+n+"个月兔子总数为:"+sum+"对");
            }else{
                flag=false;
                System.out.println("输入n的值有误,请检查后重新输入");
                System.out.println("请再次输入n的值");
                n=scanner.nextInt();
            }
            if(flag){
                break;
            }
        }

    }
}

B.递归法: f(n)=f(n-1)+f(n-2)(n>3)

1.核心代码

public static int Sum(int N){
        //如果输入的月份为第一个月或第二个月
        //那兔子的总数就为1
        if(N==1||N==2){
            return 1;
        }
        //当N>=3时,就会执行递归方法,方法内进行方法的调用
        return Sum(N-1)+Sum(N-2);
}

2.常见问题点分析

2.1 如何保证第一个月和第二个月的兔子总数为1???

解决方案: 在函数Sum里面对接收过来的值N进行判断

​ 若N值为1或者N值为2时,函数的返回值为1

2.2 f(N)=f(N-1)+f(N-2)(n>=3)的由来???

解答如下所示:
当N=3时,f(3)=1+1=f(1)+f(2)=2

当N=4时f(4)=1+2=f(2)+f(3)=3

当N=5时f(5)=2+3=f(3)+f(4)=5

因而f(N)=f(N-2)+f(N-1)=f(N-1)+f(N-2)

2.3 布尔类型变量flag的作用是什么???

​ 解答如下所示:
1.当n不符合条件时,flag=false,需要重新输入n的值

​ 然后进行下一轮的n值判断,

​ 若结果还是不符合,就重新执行上述操作

​ (重新输入n且进行判断)

​ 2.当n符合条件时,flag=true,

​ 得到兔子总数后会跳出循环

3.运行截图

3.1 首次输入有误且n=1

在这里插入图片描述

3.2 首次输入有误且n=2

在这里插入图片描述

3.3 首次输入有误且n=4

在这里插入图片描述

3.4 首次输入正确且n=6

在这里插入图片描述

4.源代码

import java.util.Scanner;
public class TestRabbit02 {
    public static void main(String[] args) {
        System.out.println("题目:古典问题:有一对兔子,从出生后第 3 个月起每个月都生一对兔子\n小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问n个月的兔子总数为多少?");
        //前提条件: 第一个月时,兔子总数为1对,第二个月时,兔子总数为1对
        System.out.println("请输入n的值:");
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        boolean flag=true;
        int sum=0;
        //定义sum变量用来存放兔子的总数
        while(true){
            if(n<1){
                //此时不满足跳出循环条件,flag值应为false
                flag=false;
                System.out.println("输入的n值(第几个月)有误,请检查后重新输入");
                System.out.println("请再次输入n的值");
                n=scanner.nextInt();
            }else{
                sum=Sum(n);
                //保证非首次输入正确的n值时,程序也能正确执行
                flag=true;
                //符合条件,跳出循环
                if (flag) {
                    break;
                }
            }
        }
        System.out.println("第"+n+"个月兔子总数为:"+sum+"对");
    }
    public static int Sum(int N){
        //如果输入的月份为第一个月或第二个月
        //那兔子的总数就为1
        if(N==1||N==2){
            return 1;
        }
        return Sum(N-1)+Sum(N-2);
    }
}
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐