二进制的妙用

原文: 二进制的妙用

很久之前就听到的这个面试题,现在一直记忆犹新。

有个店主有1000个苹果,有10个框。一会要来一个特殊的顾客,他说出一个需要的苹果数,然后店主不需要重新装苹果,只需要将特定的几个框给顾客即可满足他要的苹果数。问,店主事先应该如何将1000个苹果放到10个框里才能满足顾客提出的一次要求?(当然顾客说的苹果数是0到1000之间)

 

分析上面这个情况,也就是要构造10个数,当从10个数中取出特定的数时,其和能够表示1,1000之间的所有数。

初看这题会觉得不可思议,用10个数就可以表示[1,1000]之间的所有数!!

从最小的数开始一步步分析,要表示1,肯定得有1吧。这时有一个数1.

要表示2,可以再添加一个1,也可以添加一个2.如果添加1的话,那么表示3时又要添加一个1,所以我们选择添加2。这里有1,2

表示3的话,用1,2即可。

表示4,可以再添加一个1,或者添加4。如果添加1,那么表示5时,又得添加一个1,所以直接添加4。这时有1,2,4

身为程序员的我们这里就可以看到规律了1,2,4,8,16,32....

所以,应该是这样放苹果1,2,4,8,16,32,64,128,256,489。最后一个框没有512个苹果了,于是将所以剩下的都放其中。

 

思考这个答案的本质:

任意整数都对其对应的二进制,比如13对应(1101)2,所以可以写成(1000)2+(100)2+(1)2

而二进制的1对应整数1,二进制的10对应2,(100)2对应4,(1000)2对应8,所以用1,2,4,8,16,...这样的数可以表示所有从1到其和之间的任意整数。

BigNumber实现小数次幂,http://www.cnblogs.com/xiangism/p/4614674.html这片文章中有介绍小数二进制的一个录用。

 

回想初中时,有一次考试是用2B铅笔在答题卡上填答案,并且学号也要用2B铅笔涂出来。现在清晰地记得当时就是要我们在1,2,4,8这四个数中涂上对应的数来表示数字。当时我就非常惊讶为什么这四个数就可以表示所有1到10之间的数,是怎么想出来的???? 当了程序员最终于明白了这里的玄机。

 

以下是Java代码实现: ```java public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.print("请输入两个整数m和n(以空格隔开):"); int m = input.nextInt(); int n = input.nextInt(); System.out.println("十进制\t二进制\t八进制\t十六进制"); for (int i = m; i <= n; i++) { System.out.println(i + "\t" + toBinary(i) + "\t" + toOctal(i) + "\t" + toHexadecimal(i)); } } // 十进制转二进制 public static String toBinary(int num) { String binary = ""; Stack<Integer> stack = new Stack<Integer>(); while (num != 0) { stack.push(num % 2); num /= 2; } while (!stack.isEmpty()) { binary += stack.pop(); } return binary; } // 十进制转八进制 public static String toOctal(int num) { String octal = ""; Stack<Integer> stack = new Stack<Integer>(); while (num != 0) { stack.push(num % 8); num /= 8; } while (!stack.isEmpty()) { octal += stack.pop(); } return octal; } // 十进制转十六进制 public static String toHexadecimal(int num) { String hexadecimal = ""; Stack<Character> stack = new Stack<Character>(); int remainder; while (num != 0) { remainder = num % 16; if (remainder < 10) { stack.push((char) (remainder + '0')); } else { stack.push((char) (remainder - 10 + 'A')); } num /= 16; } while (!stack.isEmpty()) { hexadecimal += stack.pop(); } return hexadecimal; } } ``` 运行结果如下: ``` 请输入两个整数m和n(以空格隔开):25 31 十进制 二进制 八进制 十六进制 25 11001 31 19 26 11010 32 1A 27 11011 33 1B 28 11100 34 1C 29 11101 35 1D 30 11110 36 1E 31 11111 37 1F ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值