列表的纷争之二进制编码

小美:最近数学老师给我们玩了有趣的猜年龄游戏,他显示了6张表格,你只要观察这6张表格,然后回答“是”与“不是”就可以了。老师可以根据你的回答猜出你的年龄是多少。

阿福:真有这么厉害?我也想玩玩看。

小美:好的。请看下图的6张表格,然后回答“是”与“不是”。准备好了吗?

阿福:准备好了。

小美:第1张表格中是否包含了你的年龄?

阿福:不是。

小美:第2张表格中是否包含了你的年龄?

阿福:不是。

小美:第3张表格中是否包含了你的年龄?

阿福:不是。

小美:第4张表格中是否包含了你的年龄?

阿福:是。

小美:第5张表格中是否包含了你的年龄?

阿福:不是。

小美:第6张表格中是否包含了你的年龄?

阿福:是。

小美:你今年40岁。不对,你虚报年龄。这应该是你老爸的年龄才对。

阿福:没错,这就是我老爸的年龄。我不让你猜我的岁数,还不是因为你本来就知道我多大,我怕你作弊嘛。

小美:作弊?本小姐是这种人吗?我告诉你,这是科学!科学,你懂吗?

阿福:对对对,科学,科学。开个玩笑嘛。不过你这科学的力量挺强大的,还真猜出我心里想的数字了。能告诉我这背后有什么原理吗?

小美:这个嘛。。。。。。我先不告诉你,给你一张图,看你能不能找出规律来。

阿福:二进制数。

小美:没错,就是二进制数。你看出这些二进制数有什么规律了吗?

阿福:看出来了,图2表格中的每一个二进制数都跟图1表格中的十进制数一一对应。

小美:还有呢?

阿福:还有?暂时没看出来。

小美:这都看不出来?眼睛白长了。我再给你点提示吧,看看每个表格中所有的二进制数符号1的位置和表格编号的关系。

阿福:符号1的位置,表格编号。。。。。。它们有什么关系呢?再让我想想。。。。。。看到了!表格1中所有二进制数的第1位(从右往左数)都是1,表格2中所有二进制数的第2位(从右往左数)都是1,一直到表格6中所有二进制数的第6位(从右往左数)都是1。

小美:没错,正是这样!孺子可教也!

阿福:可是这样的规律又有什么用呢?

小美:有什么用?你个榆木脑袋。这样就可以计算你的年龄了啊。你刚才不是说了吗,第几张表格就对应二进制数的第几位,这个位上面是符号1,就代表你的年龄出现在了这张表格中啊。哪几张表格出现了你的年龄,就代表你的年龄对应的二进制数在这几个位上的符号是1,否则就代表这个位上的符号是0。

阿福:原来是这样。我明白了,刚才你是根据二进制数各个位的情况,转化成十进制数以后得到我的年龄的啊。让我算一算,0*2^0 + 0*2^1 + 0*2^2 + 1*2^3 + 0*2^4 + 1*2^5 = 40,完全正确。

小美:这回搞懂了吧?

阿福:总算明白了。没想到这里还隐藏着二进制编码的奥秘。不错,有点意思。对了,小美,我觉得这是一个编程的好素材啊。你不是擅长海龟作图吗,能不能用turtle把上面那两张图画出来啊。

小美:这有什么难的,不就是画几张表格吗?我只需要用一个二维列表table存储每一个表格中的数字就行了。例如table[0] = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63],表示table[0]存储了表1中的所有数字。我只要写一个函数依次把表格编号,表格线和数字画出来就行了。

题目1:

函数功能:根据输入的表格内容,画len(table)个4行col列的二维表格

函数名:draw_table(x0,y0, h, w, table)

参数表:x0, y0 -- 存储了第一张表格的左上角坐标

h, w --分别表示表格的高度和宽度

table --存储了表格内容的二维列表。

返回值:没有返回值。

代码1:def draw_table(x0,y0, h, w, table):

n = len(table)

col = len(table[0]) // 4 #每张表均分成4行col列

for i in range(n):#从上到下依次排列共n张4行col列的二维表格

y0 -= h * 5

for command in ('编号', '画线', '写字'):

if command == '编号':

tt.penup()

tt.goto(x0-40, y0-h*2)

tt.pendown()

num = ''.join(['表', str(i+1),':'])

tt.write(num,align="center", font=("黑体", 16,"normal"))

elif command == '画线':

for j in range(5):#画5条横线

x, y = x0, y0 - j * h

tt.penup()

tt.goto(x, y)

tt.pendown()

tt.forward(col * w)

tt.right(90)

for j in range(col+1):#画col+1条竖线

x, y = x0 + j * w, y0

tt.penup()

tt.goto(x, y)

tt.pendown()

tt.forward(4 * h)

tt.right(-90)

else:

for r in range(4):

x, y = x0, y0 - r * h - h /2

for c in range(col):

tt.penup()

tt.goto(x+w/2, y-h*2/5)

tt.pendown()

tt.write(table[i][r*col+c], align="center", font=("黑体", 12,"normal"))

x += w

import turtle as tt

tt.TurtleScreen._RUNNING= True  #启动绘图,在IDE中运行加这句可避免报错

tt.speed(0)

tt.ht()#隐藏笔头

table = [[1, 3, 5,7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45,47, 49, 51, 53, 55, 57, 59, 61, 63],

[2, 3, 6, 7, 10, 11, 14, 15, 18, 19,22, 23, 26, 27, 30, 31, 34, 35, 38, 39, 42, 43, 46, 47, 50, 51, 54, 55, 58, 59,62, 63],

[4, 5, 6, 7, 12, 13, 14, 15, 20, 21,22, 23, 28, 29, 30, 31, 36, 37, 38, 39, 44, 45, 46, 47, 52, 53, 54, 55, 60, 61,62, 63],

[8, 9, 10, 11, 12, 13, 14, 15, 24, 25,26, 27, 28, 29, 30, 31, 40, 41, 42, 43, 44, 45, 46, 47, 56, 57, 58, 59, 60, 61,62, 63],

[16, 17, 18, 19, 20, 21, 22, 23, 24,25, 26, 27, 28, 29, 30, 31, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,61, 62, 63],

[32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,63]]

x0, y0, h, w = -400, 600, 25, 60 #分别存储了第一张表格的左上角坐标、高度和宽度

draw_table(x0, y0,h, w, table)

tt.done()

古老师:嗯,不错,小美的海龟作图是画得越来越溜了。可美中不足的是这个存储表格信息的二维列表还是手动生成的,可惜,可惜啊!

小美:可惜?不手动生成,难道还可以自动生成?

阿福:当然可以啦。难道你没有学过列表生成式吗?

小美:列表生成式?什么是列表生成式?

古老师:列表生成式是Python内置的非常简单却强大的功能,它可以用来快速创建一个列表。例如我们要生成一个列表a = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100],只需写做a = [x * x for x in range(1, 11)]。写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来,非常简单方便。

阿福:for循环后面还可以加上if判断,这样我们就可以筛选出仅奇数的平方:a = [x * x for x in range(1, 11) if x % 2 == 1]。

小美:哦,原来是这样。我知道了,我们可以生成一个二维列表,该列表的每一个元素都是一个列表,我们可以使用列表生成式生成每一个列表元素。例如table[0] = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63],它是表1中的数字,其特征是转化成二进制数后第1位(从右往左数)都是1,我可以使用内置函数bin()把十进制数转换成二进制数,然后判断它的第1位是不是1,从而生成table[0]的值。以此类推可以生成所有的table[i]。

阿福:没错,就是这样。还可以不使用bin()函数,而是利用按位与运算来判断某个二进制数的第i位是不是1。

古老师:阿福思维很开阔,我们确实可以用多种方法来判断二进制数的某个位是1还是0。这样吧,我来分配一下任务,小美用bin()函数做,阿福用位运算做,最后看看效果是否相同。

知识小贴士:

Python bin() 函数:bin() 返回一个整数的二进制表示,其语法为bin(x),其中x是int或者long int数字,返回值是一个字符串。例如bin(10)返回'0b1010',bin(-6)返回'-0b110'。

代码2:n = 6

table = [[x for xin range(2**i, 2**n+1) if x & 2**i != 0] for i in range(n)]

代码3:n = 6

table = [[x for xin range(2**i, 2**n+1) if bin(x)[-i-1] == '1'] for i in range(n)]

table2 =[[bin(x)[2:] for x in range(2**i, 2**n+1) if bin(x)[-i-1] == '1'] for i inrange(n)]

古老师:非常好!都抓住了列表生成式的精髓,其中小美还把十进制和二进制数两个列表都生成了,很有创造性。阿福的位运算代码也很简洁,值得表扬!

对了,上次我在公园里看到一个猜姓氏的游戏,界面如下图所示。你们看看它背后的原理是什么?

小美:这不就是刚才我们玩的猜年龄游戏吗?只不过它把数字改成了姓氏,道理是一样一样的。

阿福:没错,又是一个二进制编码的游戏。

古老师:眼睛够亮的啊!既然你们都看出来了,那就用turtle把它画出来吧。

这是要用到的百家姓前128种姓氏:李王张刘陈杨赵黄周吴徐孙胡朱高林何郭马罗梁宋郑谢韩唐冯于董萧程曹袁邓许傅沈曾彭吕苏卢蒋蔡贾丁魏薛叶阎余潘杜戴夏钟汪田任姜范方石姚谭廖邹熊金陆郝孔白崔康毛邱秦江史顾侯邵孟龙万段漕钱汤尹黎易常武乔贺赖龚文庞樊兰殷施陶洪翟安颜倪严牛温芦季俞章鲁葛伍韦申尤毕聂丛焦。

我还有点事,就先走了,回头见啊。

彩蛋:

阿福:这个好像可以直接调用你前面写的draw_table()函数,只要修改一下table列表的值就行了。

小美:那当然了,这就叫做函数的通用性。还不错吧?

阿福:看你嘚瑟的,这不应该是编写函数的基本要求吗?对了,代码写好了吗?

小美:早就写好了。因为可以直接调用draw_table()函数,所以我只写了主函数部分。

代码4:import turtle as tt

tt.TurtleScreen._RUNNING= True  #启动绘图,在IDE中运行加这句可避免报错

tt.speed(0)

tt.ht()#隐藏笔头

xing = '李王张刘陈杨赵黄周吴徐孙胡朱高林何郭马罗梁宋郑谢韩唐冯于董萧程曹袁邓许傅沈曾彭吕苏卢蒋蔡贾丁魏薛叶阎余潘杜戴夏钟汪田任姜范方石姚谭廖邹熊金陆郝孔白崔康毛邱秦江史顾侯邵孟龙万段漕钱汤尹黎易常武乔贺赖龚文庞樊兰殷施陶洪翟安颜倪严牛温芦季俞章鲁葛伍韦申尤毕聂丛焦'

n = 7

table =[[xing[x-1] for x in range(2**i, 2**n+1) if x & 2**i != 0] for i inrange(n)]

x0, y0, h, w = -400, 600, 25, 60 #分别存储了第一张表格的左上角坐标、高度和宽度

draw_table(x0, y0,h, w, table)

num = input('输入二进制编码:')

print(f'{xing[int(num[::-1],2)-1]}先生/女士,你好!')

tt.done()

python的编码表_Python算法之旅列表的纷争之二进制编码相关推荐

  1. python身份证的秘密_Python算法之旅字符串游戏之身份证号的秘密

    最近在力扣(LeetCode)网闲逛,发现很多题目的官方题解都是用Python语言来描述的,这说明大家已经逐渐认识到Python语言描述算法的优越性:它语法简明,内置函数丰富,表述直截了当,可以用最简 ...

  2. python中unicode编码表_Python中的字符串操作和编码Unicode详解

    本文主要给大家介绍了关于 Python中的字符串操作和编码Unicode的一些知识,下面话不多说,需要的朋友们下面来一起学习吧. 字符串类型 str:Unicode字符串.采用''或者r''构造的字符 ...

  3. python的unicode编码表_python中Unicode编码初探

    上一篇文章主要讨论了字符编码的不同方式,这一篇文章着重谈谈对python的编码解码的理解. python2 在python2中主要有两种类型的字符类型,一个是str,一个是Unicode.平时我们默认 ...

  4. python count函数时间复杂度_Python(算法)-时间复杂度和空间复杂度

    时间复杂度 算法的时间复杂度是一个函数,它定量描述了该算法的运行时间,时间复杂度常用"O"表述,使用这种方式时,时间复杂度可被称为是渐近的,它考察当输入值大小趋近无穷时的情况 时间 ...

  5. python求数组最大值_Python算法与数据结构--求所有子数组的和的最大值

    Python算法与数据结构--求所有子数组的和的最大值 玄魂工作室秘书 玄魂工作室 昨天 题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. ...

  6. python 递归 写平方_Python算法:推导、递归和规约

    注:本节中我给定下面三个重要词汇的中文翻译分别是:Induction(推导).Recursion(递归)和Reduction(规约) 本节主要介绍算法设计的三个核心知识:Induction(推导).R ...

  7. python求梅花数_python 算法

    算法的复杂度 算法的时间复杂度是指算法需要消耗的时间资源 时间复杂度用"O(数量级)"来表示 常见的时间复杂度有: O(1)常数阶: 问题规模越大效率越高,时间不变, a = [1 ...

  8. python遍历数组冒泡排序_Python算法(一) 数组冒泡排序(难度等级:easy)

    冒泡排序(Bubble Sort)是一种典型的交换排序算法,通过交换数据元素的位置进行排序. 算法原理:从无序序列头部开始,进行两两比较,根据大小交换位置,直到最后将最大(小)的数据元素交换到了无序队 ...

  9. python表示差值_Python算法之差值查找-Testfan打卡学测开0116

    原标题:Python算法之差值查找-Testfan打卡学测开0116 本期技术分享讲师:Arthur老师 题目内容:什么是差值查找? 解析: 之前我们介绍过"二分查找"发.考虑一个 ...

最新文章

  1. 院士发言:有高校博士后待遇比国际平均水平高出一倍,这不正常!
  2. $ajax不能识别,JQuery/JS Ajax功能无法识别
  3. html视频鼠标移除不播放,html - 在Mouseover上播放Gif并在鼠标移除时暂停Gif而不替换图像? - 堆栈内存溢出...
  4. springboot中,页面访问不到静态资源
  5. java 过滤器filter使用案例
  6. DataView筛选出最新的十条数据的方法总结;
  7. scala的list源码解密
  8. MEncoder的基础用法—6.2. 选择输入文件或设备
  9. 软件测试 | 测试计划包含什么内容
  10. Quartz定时任务框架(一)
  11. 山东法律学校97级二班计算机班,关于表彰全国三好学生、全国优秀学生干部和全国先进班集体及其标兵的决定...
  12. phpstudy和php,phpstudy和wamp哪个好
  13. IOS回调机制——代理,通知中心以及Block
  14. ggplot绘制小提琴图
  15. flex 实现水平布局 三等分
  16. 小说阅读大全(安卓)最后一个绿色版。
  17. 触摸芯片电路布局和走线设计注意事项
  18. 好家伙谷歌翻译又不能用了(有效解决方法)
  19. 闪迪u盘不能识别好办法_SanDisk U盘无法被64位Windows7电脑识别
  20. Amber进行DNA建模详细步骤

热门文章

  1. 使用Java SE8 Streams 处理数据,Part 2
  2. 设置 IntelliJ IDEA 主题和字体的方法
  3. [机器学习与数据分析] 数据分析常用方法
  4. Windows 11通过WSA及ADB运行安卓应用
  5. 冰蝎各版本工具分析与魔改思路
  6. 狸窝音频剪辑软件_5分钟学会影视剪辑:账号注册、素材寻找、剪辑使用、获取收益...
  7. 这台笔记本最适合程序员编程!
  8. 科技云报道:乘风破浪的联通沃云,是一朵安全可控的国产云
  9. 2021年数学建模国赛C题思路
  10. Android ItemTouchHelper实现RecyclerView交互动画