微软的面试题:用4位数编码0-9

2015年5月微软的一道面试题:

来源:同学叙述

题目:

用0,2,4,6表示0-9任意的数字组成的序列。

分析:

乍一看,就是编码部分的知识。我们知道一位中有4个有效信息位:分别是0,2,4,6,它们要表示一个10位的信息:0-9。

(*在这里,肯定有很多人想到了哈夫曼编码什么的,我觉得这里应该是未知0-9这十个数的概率分布的,所以用哈夫曼编码并不合适。

当然了,在面试中你要提前先问清楚,作为你思考的一个过程。)


最先想到的可能就是用两个四位信息位表示一位10位信息位,4^2 = 16 > 10,可以满足。平均编码长度为2位。

对应关系为

编码对应的数字
000
021
042
063
204
225
246
267
408
429
44保留
46保留
60保留
62保留
64保留
66保留

接着我们进行优化,考虑的就是减少编码长度,因为考虑到16位中是有浪费的,所以比较容易得会想到用3*3+1的方式:

即所谓的把0,2,4三个数字当作一个信息位,那么用两位就可以表示出9位信息位,然后再用6表示余下一位。

这样的方式有如下对应关系:

编码对应的数字
000
021
042
203
224
245
406
427
448
69
这样子,平均的编码长度为(2 * 9 + 1)/ ( 9 + 1 )= 1.9位。
(*写到这里,也许有人可能想到上面第一种方法中也可以进行优化,即用44-66的6位表示其他两位数字,比如用44表示00,这样就可以在一定程度上减少编码长度)


再思考:

但是上面的第二种方法并不是最优,或者说不是思考的尽头。

我们不妨假设0-9出现的概率相同,那么6对应的9的编码长度是1,其实只是减少了所有字符中1/10的长度,可以看到减少的长度很有限,因为另外有9/10的编码长度还是2的。

所以并不是最优的,我们应该朝怎么样把整体的编码长度有效降低。

这里,就有信息有效位的概念(我自己瞎想的)

对于0,2,4,6,其有效位是4,那么如果有n位就能表示4^n种的信息状态,而对于0-9,需要表示的是10种信息,如果有m位,则有10^m。

前提:需要表示的信息概率分布相同(也就是出现的概率差不多)时

要想编码长度最短,其实就是找到n和m,使4 ^ n >= 10 ^ m,并且使其中的(4 ^ n - 10 ^ m) / 10 ^ m尽量小,也就是浪费掉的或者说保留掉的位占得比率尽可能小。

我们可以找到,当n = 5时,m = 3时,可以满足上述条件,刚好是4 ^ 5 = 2 ^ 10 = 1024 > 1000 。

因此,我们也就相当于用5位表示了3位,平均编码长度为5 / 3 = 1.67位。

*这里的1.67是在0-9任意的数字组成的序列比较长的情况下的,而不是针对它们序列很短的时候,后者肯定是短编码比较好。

编码对应的数字
00000000
00002001
00004002
......
66426999
66440保留
......
66666保留


但是呢,这里会出现一个问题,就是当我们用5位表示3位的时候,如果遇到序列并不是3的倍数的怎么办,我们如何来表示末尾的比如“3空空”或“34空”之类的数字呢。

这里我们可以用保留的位数做文章。

比如令66440表示末尾刚好是不用截取的,即刚好是3的倍数的。

令66442表示截取1位的,即刚好是3倍数多1位的。

令66444表示截取2位的,即刚好是3倍数多2位的。

那么对于9990的话,我们就可以编码:66426 00000 66442来进行编码。

所以,是可以完美解决5位编码3位的问题的,平均编码长度为1.67,应该是最短的。


再思考:

不过,这里还有一个小问题:虽然编码长度短了,但是,对于编码和接码过程中需要维护的映射关系却长了,比如第一第二种方法都只用维护10个映射关系即20空间大小,而对于第三种方法却需要维护1000各映射关系即2000个空间大小。这对于内存和处理来说会比较麻烦,但是至少在传输过程中会比较轻便。

这也和现实生活中很像,你要想路上轻便点,就需要多花点时间打包整理好行李。

——Apie陈小旭







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值