编程题:斐波那契数列(兔⼦繁衍问题)---⾯向对象版
最简单的版本:每⼀项等于前两项之和,这个⽤递归或者循环就可以解决。
这⾥我们延伸出⼀个⽣活中兔⼦繁衍的实际案例:⼀开始有 A 只兔⼦,每只兔⼦ B 个⽉后可以⽣出 C 只⼩兔⼦,兔⼦在第 D 个⽉之后会死亡。如图
展⽰了A=1,B=2,C=2,D=3的情况下兔⼦繁衍过程
这⾥我们使⽤⾯向对象的思维解决
⾸先是建模:
第⼀个我们定义兔⼦窝,它有窝⾥兔⼦、兔⼦寿命、兔⼦繁殖年龄、兔⼦每次繁殖数量4个属性,还有增加兔⼦、移除兔⼦、获取N⽉后兔⼦数量3个⾏为。
第⼆个我们定义兔⼦,它有年龄1个属性,还有成长、繁殖、死亡3个⾏为。
1、兔⼦窝
先看代码
/**
* 兔⼦窝
*/
static class RabbitHome {
// 窝⾥兔⼦
private final List<Rabbit> rabbitList;
// 兔⼦寿命
private final int lifeSpan;
// 兔⼦繁殖年龄
private final int breedAge;
// 兔⼦每次繁殖数量
private final int everyBreedNum;
public RabbitHome(List<Rabbit> rabbitList, int lifeSpan, int breedAge, int everyBreedNum) {
this.rabbitList = rabbitList;
this.lifeSpan = lifeSpan;
this.breedAge = breedAge;
this.everyBreedNum = everyBreedNum;
}
/**
* 添加兔⼦
*
* @param rabbit 兔⼦
*/
public void addRabbit(Rabbit rabbit) {
rabbitList.add(rabbit);
}
/**
* 移除兔⼦
*
* @param rabbit 兔⼦
*/氢氧化物
public void removeRabbit(Rabbit rabbit) {
}
/**
* 获取兔⼦数量
*
* @param months 第⼏个⽉
* @return 窝⾥兔⼦数量
时间旅行者的妻子
*/
public int getRabbitCount(int months) {
if (months < 1) {
return rabbitList.size();
宝格丽品牌介绍}
for (int i = 0; i < months; i++) {
for (Rabbit rabbit : rabbitList) {
人口流入// 成长
// 繁殖
if (rabbit.age >= breedAge) {
rabbit.breed(this, everyBreedNum);
重计量}
// 死亡
if (rabbit.age == lifeSpan) {
rabbit.die(this);
}
}
}
return rabbitList.size();
}
}
重点是获取兔⼦数量这个⽅法,需要模拟兔⼦每⽉之后的繁衍过程。
有了兔⼦窝,需要⼀个兔⼦窝⼯⼚负责其创建过程。因为兔⼦繁衍需要迭代过程中对集合进⾏修改,所以使⽤CopyOnWriteArrayList。
* 兔⼦窝⼯⼚
*/
static class RabbitHomeFactory {
/**
* 创建兔⼦窝
*
* @param initialRabbitNum 开始兔⼦数量
* @param lifeSpan 寿命
* @param breedAge 繁殖年龄
* @param everyBreedNum 每次繁殖数量
* @return 兔⼦窝
*/d小调幻想曲
public static RabbitHome create(int initialRabbitNum, int lifeSpan, int breedAge, int everyBreedNum) { if (initialRabbitNum < 1 || lifeSpan < 1 || breedAge < 1 || everyBreedNum < 1) {
throw new IllegalArgumentException("存在参数⼩于1");
}
读书使人优美
List<Rabbit> rabbitList = new CopyOnWriteArrayList<>();
for (int i = 0; i < initialRabbitNum; i++) {
rabbitList.add(new Rabbit(0));
}
return new RabbitHome(rabbitList, lifeSpan, breedAge, everyBreedNum);
}
}
2、兔⼦
兔⼦的成长就是年龄加1,繁殖就是往兔⼦窝增加新的兔⼦,死亡就是从兔⼦窝移除⾃⼰。
* 兔⼦
*/
static class Rabbit {
// 年龄
private int age;
public Rabbit(int age) {
this.age = age;
}
/**
* 成长
*/
public void grow() {
age++;
}
/**
* 繁殖
*
* @param rabbitHome 兔⼦窝
* @param everyBreedNum 每次繁殖数量
*/
public void breed(RabbitHome rabbitHome, int everyBreedNum) {
for (int i = 0; i < everyBreedNum; i++) {
rabbitHome.addRabbit(new Rabbit(0));
}
}
/**
* 死亡
*
* @param rabbitHome 兔⼦窝
*/
public void die(RabbitHome rabbitHome) {
}
}
3、测试
就测试下开头图⽚那个过程吧
public static void main(String[] args) {
/*
* 第0个⽉存在兔⼦数量:1
* 第1个⽉存在兔⼦数量:1
* 第2个⽉存在兔⼦数量:3
* 第3个⽉存在兔⼦数量:4
* 第4个⽉存在兔⼦数量:8
* 第5个⽉存在兔⼦数量:14
* 第6个⽉存在兔⼦数量:24
*/
for (int i = 0; i <= 6; i++) {
RabbitHome rabbitHome = ate(1, 3, 2, 2);
System.out.println("第" + i + "个⽉存在兔⼦数量:" + RabbitCount(i)); }
}
结果如下
下⾯附上⼀个类装下的全部代码,当然实际别这么⼲
import java.util.List;
import urrent.CopyOnWriteArrayList;
/**
* 斐波那契数列(兔⼦繁衍问题):
* ⼀开始有 A 只兔⼦,每只兔⼦ B 个⽉后可以⽣出 C 只⼩兔⼦,兔⼦在第 D 个⽉之后会死亡。
* 求第N个⽉兔⼦数量
*/
public class Fibonacci {
public static void main(String[] args) {
/*
* 第0个⽉存在兔⼦数量:1
* 第1个⽉存在兔⼦数量:1
* 第2个⽉存在兔⼦数量:3
* 第3个⽉存在兔⼦数量:4
* 第4个⽉存在兔⼦数量:8
* 第5个⽉存在兔⼦数量:14
* 第6个⽉存在兔⼦数量:24
*/
for (int i = 0; i <= 6; i++) {
RabbitHome rabbitHome = ate(1, 3, 2, 2);
幼儿园春季开学温馨提示System.out.println("第" + i + "个⽉存在兔⼦数量:" + RabbitCount(i));
}
}
/**
* 兔⼦窝
*/
static class RabbitHome {
// 窝⾥兔⼦
private final List<Rabbit> rabbitList;
// 兔⼦寿命
private final int lifeSpan;
// 兔⼦繁殖年龄
private final int breedAge;
// 兔⼦每次繁殖数量
private final int everyBreedNum;
public RabbitHome(List<Rabbit> rabbitList, int lifeSpan, int breedAge, int everyBreedNum) { this.rabbitList = rabbitList;
this.lifeSpan = lifeSpan;
this.breedAge = breedAge;
this.everyBreedNum = everyBreedNum;
}
/**
* 添加兔⼦
*
* @param rabbit 兔⼦
*/
public void addRabbit(Rabbit rabbit) {
rabbitList.add(rabbit);
}