一共有多少条鱼?

题目:一条鱼每个月都可以生产10条小鱼,小鱼3个月后才可以生产,问如果一开始有1条鱼,那么1年内一共会有多少条鱼?

如果直接用java代码实现会比较容易,首先写一个Fish类:

package sang;


import java.util.ArrayList;
import java.util.List;


public class Fish {
	// 出生月份
	private int bornMonth;
	// 能否生鱼
	private boolean canProduce = false;
	// 生鱼数量
	private int amount = 10;


	public Fish() {


	}


	public Fish(int amount) {
		this.amount = amount;
	}


	public Fish(int bornMonth, boolean canProduce) {
		this.bornMonth = bornMonth;
		this.canProduce = canProduce;
	}


	public int getBornMonth() {
		return bornMonth;
	}


	public void setBornMonth(int bornMonth) {
		this.bornMonth = bornMonth;
	}


	public boolean isCanProduce() {
		return canProduce;
	}


	public void setCanProduce(boolean canProduce) {
		this.canProduce = canProduce;
	}


	public int getAmount() {
		return amount;
	}


	public void setAmount(int amount) {
		this.amount = amount;
	}


	//生产小鱼
	public List<Fish> produce(int bornMonth) {
		List<Fish> fishes = new ArrayList<Fish>(amount);
		for (int i = 0; i < amount; i++) {
			Fish f = new Fish();
			f.setBornMonth(bornMonth);
			f.setCanProduce(false);
			fishes.add(f);
		}
		return fishes;
	}


}

再写一个测试类,该类中有一个count方法如下:

/*
	  	保存数量
		static int count = 0;
		生鱼周期
		int cycle = 3;
		12个月
		int year = 12;
	 */
	public long count(Fish mother) {
		//保存鱼
		List<Fish> sons = new ArrayList<Fish>();
		// 保存数量
		long result = 0;
		Fish fish = null;
		// 队列中的索引
		int index = 0;
		//循环1年之内
		for (int currentMonth = 1; currentMonth <= year; currentMonth++) {
			index = 0;

			// 母鱼每个月都生产
			// 加入到队列中
			sons.addAll(mother.produce(currentMonth));
			while (index < sons.size()) {
				// 从队列中取鱼
				fish = sons.get(index);
				if (fish != null) {
					// 是否能生产
					if (fish.isCanProduce()
							|| ((currentMonth - fish.getBornMonth()) >= this.cycle)) {
						fish.setCanProduce(true);
						// 将此鱼生产的小鱼加入到队列中
						sons.addAll(fish.produce(currentMonth));
					}
					index++;

				}
			}
		}

		result = sons.size();
		return result;
	}


该方法能够计算出一年内一共会有多少条鱼,该方法中用ArrayList来保存鱼对象,最后计算出长度可得鱼的数量。但是实际的数量会特别大,所以会很占用内存,甚至会出现内存溢出的情况,如果你是2GB的内存,则amount设置为10个鱼可以运行,但如果20、50或100的情况下会OutOfMemoryError,所以该方法不现实,但是这样做思路却很清晰。那么根据上述代码即可产生如下计算:

假设1月份开始有一条鱼,那么它可以生产m条小鱼,小鱼过3个月后,也就是4月份才可以生产,那么1月份到3月份的鱼的个数分别为m、m、m。到4月份的时候,1月份生产的小鱼开始生产,每个鱼生产m条,那么4月份鱼的总数为m+m*m。所以5月份的时候鱼的总数为m+2(m*m)(加上了4月份生产的小鱼),6月份的时候鱼的总数为m+3(m*m)(加上了5月份生产的小鱼),以此类推...


按此种方法计算,实现的代码为:

	public long count2(int amount) {
		//生产数量
		int m = amount;
		//计算公式
		int[] f = new int[] { m, m, m };
		int x = m;
		//前3个月
		long result = 3 * m;
		int k = 0;
		//从第4个月开始
		for (int i = 4; i <= 12; i++) {
			if (k < cycle) {
				x = x + m * f[k];
				result += x;
				f[k] = x;
				k++;
			} else {
				k = 0;
				i--;
			}

		}
		return result;
	}
由于不再保存Fish对象仅根据上述分析公式计算结果, 只要结果不超出long的范围就不会有异常。该方法很简单,就是根据上述分析写出。

测试一下:

amount=10的时候,结果为:210620

amount=20的时候,结果为:2866240

amount=100的时候,结果为:1556451200

如果用第一种方法呢?

amount=10的时候,结果为:210620

amount=20的时候,结果为:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

最后说一下,此文章本人原创,也是没事的时候想到的题目就写了一下,希望大家指点!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值