古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
程序分析:兔子的规律为数列1,1,2,3,5,8,13,21...斐波那契数列
==》从中发现,从第三个月开始,前两个月兔子数之后为第三个兔子总数,所以定义一个存放24个月兔子书数组,每个元素存放一个月的兔子总数
使用斐波那契数列的思想解决此问题,如下:
public class Test1 {
public static void main(String args[]) {
// 设置过了几个月
Scanner read = new Scanner(System.in);
int month = 1;
while (month != 0) {
month = read.nextInt();
//输出几月后兔子的总的对数
for(int i=0; i<month;i++){
System.out.println("第"+(int)(i+1)+"月:"+fun(i+1));
}
}
read.close();
}
public static int fun(int n){
if(n == 1 || n == 2){
return 1;
}
return fun(n-1)+fun(n-2);
}
}
在已知的规律之下可以这样计算,那么如果其没有规律和突然改变了规律该怎么计算?
作为一个程序员,用面向对象的思想去解决比较好,一下是本人通过面向对象的思想解决此问题的方法。
首先,需要明确此题目的主要的对象是什么?兔子。那么兔子做过什么事情?生小兔子。然后与兔子自身的什么属性又联系?年龄(月)和它的孩子
Rabbit.java
/*
* 兔子类
*/
public class Rabbit {
//兔子的年龄-月
private int age;
//兔子的孩子
private List<Rabbit> child;
//创建一个实例表示出生且为1--因为生下它自后要隔一个月之后再生--所以出生的时候其实可一看做过了一个月
public Rabbit(){
this.age = 1;
child = new ArrayList<>();
}
//生兔子操作--先让自己的孩子生-有子至父--每隔一个月生一次
public void born(){
this.age++;
//年龄加一月-----必须在前面加,因为在此生的时候相当于在其上一次出生的下一个月,已经过了两个月,
//且题目要求在第三个月开始生,相当于生下后隔一个月以后,孩子在第二次执行此行为的时候就可以生了-即age为3了
if(this.child.size() != 0){
for(Rabbit r : child){
r.born();
}
}
//生小兔子基本细节--当age为3时才生兔子,否则不生
if(this.age >= 3){
this.child.add(new Rabbit());
}
}
//统计总兔子的数目--所有的兔子|自己的子孙。。。
public int getSum(int num){
if(this.child.size() == 0){
return num;
}else{
num = num +this.child.size();
for(Rabbit r:child){
num = r.getSum(num);
}
}
return num;
}
}
Test.java
public class Test {
public static void main(String args[]){
//首先出生一对兔子
Rabbit rabbit = new Rabbit();
//设置过了几个月
Scanner read = new Scanner(System.in);
int month = 1;
month = read.nextInt();
System.out.println("第 1月:"+1);
//出生为第一个月。。以下从第二个月算起
for(int i = 2; i<=month;i++){
rabbit.born();
System.out.println("第 "+i+"月:"+rabbit.getSum(1));
}
//统计兔子的总数
//System.out.println(rabbit.getSum(1));//从1开始计数--以‘对'为单位--开始有一对兔子
read.close();
}
}