编程题:斐波那契数列(兔子繁衍问题)---面向对象版

最简单的版本:每一项等于前两项之和,这个用递归或者循环就可以解决。

这里我们延伸出一个生活中兔子繁衍的实际案例:一开始有 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) {
            rabbitList.remove(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) {
                    // 成长
                    rabbit.grow();
                    // 繁殖
                    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 兔子窝
         */
        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) {
            rabbitHome.removeRabbit(this);
        }
    }

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 = RabbitHomeFactory.create(1, 3, 2, 2);
            System.out.println("第" + i + "个月存在兔子数量:" + rabbitHome.getRabbitCount(i));
        }
    }

结果如下

下面附上一个类装下的全部代码,当然实际别这么干🙂

import java.util.List;
import java.util.concurrent.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 = RabbitHomeFactory.create(1, 3, 2, 2);
            System.out.println("第" + i + "个月存在兔子数量:" + rabbitHome.getRabbitCount(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);
        }

        /**
         * 移除兔子
         *
         * @param rabbit 兔子
         */
        public void removeRabbit(Rabbit rabbit) {
            rabbitList.remove(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) {
                    // 成长
                    rabbit.grow();
                    // 繁殖
                    if (rabbit.age >= breedAge) {
                        rabbit.breed(this, everyBreedNum);
                    }
                    // 死亡
                    if (rabbit.age == lifeSpan) {
                        rabbit.die(this);
                    }
                }
            }
            return rabbitList.size();
        }
    }

    /**
     * 兔子窝工厂
     */
    static class RabbitHomeFactory {

        /**
         * 创建兔子窝
         *
         * @param initialRabbitNum 开始兔子数量
         * @param lifeSpan 寿命
         * @param breedAge 繁殖年龄
         * @param everyBreedNum 每次繁殖数量
         * @return 兔子窝
         */
        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);
        }
    }

    /**
     * 兔子
     */
    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) {
            rabbitHome.removeRabbit(this);
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值