古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
程序中的bearAge为3时,即为题目中的3个月,也可以为任意大于等于2个月后生。
package algorithm.fibonacci;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class RabbitService {
class Rabbit {
public int age;
public Rabbit() {
this.age = 1;
}
public Rabbit(int age) {
this.age = age;
}
}
/*
* 面向对象方法
*/
public void printRabbit(int month, int bearAge) {
if (month > 0) {
long start = System.currentTimeMillis();
// 保存每个月份的兔子数目
long[] rabbitNumbersArray = new long[month];
// rabbitList保存所有的兔子,在第一个月有一对大兔子
Rabbit bigRabbit = new Rabbit();
List<Rabbit> rabbitList = new ArrayList<Rabbit>();
rabbitList.add(bigRabbit);
rabbitNumbersArray[0] = rabbitList.size();
// 从第二个月开始计算,如果兔子刚生下来age为1,则age为3时兔子才能生兔子
for (int currentMonth = 2; currentMonth <= month; currentMonth++) {
int lastMonthRabbitNumber = rabbitList.size();
for (int i = 0; i < lastMonthRabbitNumber; i++) {
Rabbit rabbit = rabbitList.get(i);
rabbit.age++;
if (rabbit.age >= bearAge) {
rabbitList.add(new Rabbit());
}
}
rabbitNumbersArray[currentMonth - 1] = rabbitList.size();
}
long end = System.currentTimeMillis();
System.out.println("1月到" + month + "月的兔子数目为:"
+ Arrays.toString(rabbitNumbersArray) + ",使用时间为"
+ (end - start));
} else {
System.out.println("输入月份必须大于0");
}
}
/*
* 作用递归方法计算费式数列,当兔子生育月不为3时,也可以计算
*/
public void printRabbit2(int month, int bearAge) {
if (month > 0) {
long start = System.currentTimeMillis();
long[] rabbitNumbersArray = new long[month];
for (int i = 1; i <= month; i++) {
rabbitNumbersArray[i - 1] = fibonacci(i, bearAge);
}
long end = System.currentTimeMillis();
System.out.println("1月到" + month + "月的兔子数目为:"
+ Arrays.toString(rabbitNumbersArray) + ",使用时间为"
+ (end - start));
} else {
System.out.println("输入月份必须大于0");
}
}
private int fibonacci(int n, int bearAge) {
if (n < bearAge) {
return 1;
} else {
return fibonacci(n - 1, bearAge)
+ fibonacci(n - (bearAge - 1), bearAge);
}
}
/*
* 根据费式数列特点,当前值为前两项之和
*/
public void printRabbit3(int month, int bearAge) {
if (month > 0) {
long start = System.currentTimeMillis();
long[] rabbitNumbersArray = new long[month];
int currentMonth = 0;
for (currentMonth = 1; currentMonth < bearAge; currentMonth++) {
rabbitNumbersArray[currentMonth - 1] = 1;
}
for (currentMonth = bearAge; currentMonth <= month; currentMonth++) {
rabbitNumbersArray[currentMonth - 1] = rabbitNumbersArray[currentMonth
- bearAge]
+ rabbitNumbersArray[currentMonth - 2];
}
long end = System.currentTimeMillis();
System.out.println("1月到" + month + "月的兔子数目为:"
+ Arrays.toString(rabbitNumbersArray) + ",使用时间为"
+ (end - start));
} else {
System.out.println("输入月份必须大于0");
}
}
public static void main(String[] args) {
RabbitService service = new RabbitService();
int bearAge = 3;
service.printRabbit(20, bearAge);
service.printRabbit2(20, bearAge);
service.printRabbit3(20, bearAge);
}
}
输出:
1月到20月的兔子数目为:[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765],使用时间为6
1月到20月的兔子数目为:[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765],使用时间为2
1月到20月的兔子数目为:[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765],使用时间为0
2220

被折叠的 条评论
为什么被折叠?



