关于Java实现“1000个鸡蛋/苹果分装到10个篮子/箱子里,可表述1000以内任何正整数”的程序

        前两天上课,车老师留了个课后作业,想考察一下我们还剩下多少Java水平。具体要求是将1000个鸡蛋分到10个箱子里,实现随机输入一个1000及以内的数字,都可以用这十个箱子来表示。一年多没碰过Java的我当时还没意识到问题的严重性,回到宿舍想破头也没想出来如何实现。后来实在没办法了,查了一下,才得知考查的是二进制,实在惭愧。我把参考的文章放在下面:1000个苹果,放到10个框里,怎么样保证任意数量的苹果都可以被表示出来

        接下来我就拾人牙慧,复述一下算法思想。

        1000是接近1024的数字,1024也就是2的10次方。那么用2的i次方(0<=i<10)依次装十个箱子,就可以表述1024以内所有的数字(因为1023转换为二进制是1111111111)。于是我们从小到大开始装箱子:

箱子编号12345678910
鸡蛋数目1248163264128256489

        因为装到第十个箱子时,前面已经装了511个鸡蛋了,那第10个箱子只能装1000-511=489个鸡蛋了。接下来我们要做的就是把用户给出的数字转换为二进制, 然后每一位对应上述编号的箱子,例如第一位就对应第一个箱子...,以此类推。

        假如用户给出了数字13,转换为二进制就是 0000001101 ,那么我们只需要取出第一、三、四个箱子即可,结果是1+4+8=13。看似很完美对吗,但其实有一个大问题,就是我们第十个箱子本应该放512个鸡蛋,但最终因为数量不够放了489个鸡蛋,那么只要用户给出的数字大于等于512,转换为二进制后,第十位必然是1,本来我们要用第十个箱子里的512个鸡蛋,但现在只有489个了,差了23个,怎么办?

        解决方法就是在用户输入数据后,自己先判断一下是不是小于512,如果小于512,那我们什么也不用变,因为用不到第十个箱子;如果大于512,那我们就人为把第十个箱子先取出来,默认已经使用第十个箱子了,然后把用户给出的数据-489,剩下的鸡蛋数再让他转换为二进制,剩下的就跟上面一样了。

        那么基本算法思想已经叙述完了,具体就是程序实现了。由于也是初学者,代码水平实在一般,若有大佬不吝赐教,实在感激。

import java.util.*;

/*1000个鸡蛋,一次性放入10个箱子中,放好后数量不能改变
要求:在1000以内随便报一个数,得出搬哪几个箱子即可完成*/

public class EggAssignment {
	public static void splitLine() {
		System.out.println("—————————————————————————————————————————————————————————————————————————————————");
	}
	public static void main(String[] args) {
		//生成存放鸡蛋的十个盒子
		int[] eggBox = new int[10];
		//生成存放转化为二进制的数字
		int[] key_2 = new int[10];
		//生成scanner对象sc用以接收键盘输入
		Scanner sc = new Scanner(System.in);
		/*key用来接收键盘输入,sum用以累加计算取出鸡蛋的总数
		jugde用于判断是否让用户继续输入*/
		int key=0,sum=0;
		boolean jugde = true;
		//初始化数组末尾(第10个箱子)
		eggBox[eggBox.length-1] = 489;
		//用二进制初始化数组(前9个箱子)
		for (int i = 0; i < 9 ; i++) {
			eggBox[i] = (int) Math.pow(2, i);
		}
		
		//输出箱子里放鸡蛋的数目
		splitLine();
		for (int i = 0; i < eggBox.length; i++) {
			System.out.print("第"+(i+1)+"个箱子\t");
		}
		System.out.println();
		splitLine();
		for (int i = 0; i < eggBox.length; i++) {
			System.out.print(eggBox[i]+"个\t");
		}
		System.out.println();
		splitLine();
		
		/*用户交互 while循环限定用户只能输入1000及以内的数据
			bug:输入非整型数据会报异常
			处理:使用try-catch抓取异常 令用户重新回到循环输入正确数据*/
		System.out.print("请输入1000以内的整数:");
		while(jugde) {
			try {
				key = sc.nextInt();
				while(key>1000) {
					splitLine();
					System.out.println("输入有误,请重新输入");
					System.out.print("请输入1000以内的整数:");
					key = sc.nextInt();
				}
				jugde = false;
			} catch (InputMismatchException e) {
				splitLine();
				System.out.println("输入有误 请勿输入大于1000的整数及非整数!");
				System.out.print("请重新输入1000以内的整数:");
				sc = new Scanner(System.in);
			}
		}
		
		//释放Scanner类对象sc调用的资源
		sc.close();
		
		//除二取余法将十进制转化为二进制
		//分两种情况,小于512则直接取出盒子  大于512默认先取出第十个盒子 剩下的拿前9个盒子表示
		//小于512直接转换二进制 大于512先减去489再转换二进制
		if(key<512) {
			for (int i = 0; i < 10 ;i++) {
			key_2[i]=key%2;
			key=key/2;
			} 
		}else {
			key=key-489;
			for (int i = 0; i < 9 ;i++) {
			key_2[i]=key%2;
			key=key/2;
			} 
			key_2[9]=1;//默认第十个箱子被取出
		}
		//将二进制数组下标为1时 取出对应盒子的鸡蛋
		System.out.print("共");
		for (int i = 0; i < 10; i++) {
			if(key_2[i]==1) {
				System.out.print("第"+(i+1)+"个箱子 ");
				sum = sum + eggBox[i];
			}
		}
		System.out.println("被取出");
		System.out.println("成功取出了 "+sum+" 个鸡蛋!");
	}
}

程序运行结果如下:

 

         再次感谢-Mei-的文章,给我了很大启发,不然现在还看不懂问题要求,十分感激!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值