读数系统-第11届蓝桥杯国赛Python真题精选

读数系统-第11届蓝桥杯国赛Python真题精选_第1张图片

[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第33讲。

读数系统,本题是2020年10月30日举办的第11届蓝桥杯青少组Python编程国赛真题,题目要求设计一个读数系统,将输入的数字按照中文读写的规范转为汉语拼音字串。

先来看看题目的要求吧。

一.题目说明

提示信息:

假设给出一个数值9876543201,直接看这个数字很难直观准确的读出来,为了准确快速的读出一个数字,想请你编写一个读数系统。

读数系统-第11届蓝桥杯国赛Python真题精选_第2张图片

中文读数规则:

1). 从高位读起,先读亿级,再读万级,最后读个级;

2). 读亿级和万级时按读个级的方法来读,读完亿级后加上一个“亿”字,读完万级后加上一个“万”字;

3). 每级末尾不管有几个0都不读,每级中间和前面有一个或连续几个0,都只读一个0。

编程实现:

输入一个小于一百亿的正整数n(1 ≤ n < 10000000000),按照中文读写的规范转为汉语拼音字串,相邻的两个音节用一个空格符隔开。

例如:给定一个阿拉伯数字串“9876543201”

中文读写的规范:九十八亿七千六百五十四万三千二百零一

汉语拼音字串:jiu shi ba yi qi qian liu bai wu shi si wan san qian er bai ling yi

输入描述:

输入一个小于一百亿的正整数n(1≤n<10000000000)

输出描述:

输出其对应汉语拼音字串,相邻的两个音节用一个空格符隔开

样例输入:

54321001

样例输出:

wu qian si bai san shi er wan yi qian ling yi

二.思路分析

这是一道模拟算法题,考查的知识点主要包括字符串、列表和函数。

根据题目的要求,数字的范围为1~10000000000,很显然数字规模比较大,不适合挨个处理。

还记得我们的计算思维吗,就是如何将复杂问题拆分成简单问题。

读数系统-第11届蓝桥杯国赛Python真题精选_第3张图片

仔细分析一下,你会发现个级、万级和亿级的读法是一样的,比如:

123412341234一千二百三十四亿一千二百三十四万一千二百三十四

除了单位不同,其数字部分的读法完全一致,因此我们只需要先处理好4位数字的读法,再进行连接就可以了,但是这里有一个特殊情况,就是数字零,需要重点分析和处理。

因此,我们可以将问题拆分为如下3个步骤:

  • 实现4位数字的读法;

  • 将输入数字分为3段处理;

  • 考虑并完善特殊情况;

4位数的读法是解决问题的第一步,也是最重要的一步,由于Python不能自动将数字转成汉语拼音,所以要先定义好每个数字和单位的拼音。

我们可以使用列表来保存这些拼音,数字的拼音列表可以定义如下:​​​​​​​

# 定义数字的拼音number = ["ling","yi","er","san","si","wu","liu","qi","ba","jiu"]

单位的拼音列表可以定义如下:​​​​​​​

# 定义单位的拼音unit = ["qian","bai","shi",""]

注意,个位是不需要读出来的,所以将其定义为空,保留这一位是方便理解和计算。

然后使用循环4位数字串进行遍历,将每个数字的拼音和单位进行连接,比如数字为:

8765

先获取第一个数字8,通过下标获取number列表中的拼音number[8] = "ba",同时通过unit列表找到其对应的单位"qian",将二者连接起来,就是"ba qian"。

再依次处理数字7、6、5,最后可以得到完整的拼音”ba qian qi bai liu shi wu“。

当然,这是理想状态,还需要考虑两种特殊情况:

  • 位数不足4位;

  • 数字包含0;

位数不足4位时,在循环处理时,数字的拼音是正常的,但是单位不能一一对应,需要额外处理一下,比如只有3位数字时,最高是百,因此需要数字的长度来计算其下标。

数字包含0时,问题就变得复杂了一些,包括两种情况:

1). 末尾数字是0时,0是不读的;

2). 有连续的0时,只需要读1次;

为了方便,我们可以将这个处理过程定义成函数,然后再将输入的数字拆分成3段,也就是亿级、万级和个级,分别调用函数获取其拼音字符串,再考虑一些特殊情况,就可以得到完整的汉语拼音串了。

思路有了,接下来,我们就进入具体的编程实现环节。

三.编程实现

根据上面的思路分析,我们分4步来编写程序:

  • 定义列表

  • 定义函数读取4位数

  • 分段处理

  • 完善程序

1. 定义列表

这一步比较简单,定义两个列表,分别是数字拼音和单位拼音,代码如下:

读数系统-第11届蓝桥杯国赛Python真题精选_第4张图片

2. 定义函数读取4位数

根据前面的思路分析,我们定义函数如下:

读数系统-第11届蓝桥杯国赛Python真题精选_第5张图片

代码不少,说明6点:

1). 读取数字时,是以字符串的方式来处理的,所以代码都是围绕着字符串处理进行的;

2). 在获取数字拼音时,需要先获取字符对应的数字即s[i],再将s[i]作为下标获取拼音,不过要使用int()函数将其转成整型; 

3). 在获取单位的时候,下标不仅和i有关系,和字符串的长度l也有关系;

4). 对于连续数字0的处理,这里使用了一个变量"flag",如果当前数数字为0,就将flag设为1,否则设置为0,再根据这个flag来决定是否需要连接”ling“和单位拼音;

5).对于末尾数字0的处理,如果末尾为0,则删除字符串末尾的"ling",当然如果数字本身为0,则不用删除;

6). 由于在连接时,会在每个拼音后面增加一个空格,所以在得到完整的字符串后,使用rstrip()函数删除末尾的空格,这可以避免两个拼音之间出现两个空格的情况。

完成这一步,建议先测试一下,确保代码和逻辑的正确性,再继续下一步。

3. 分段处理 

有了read_number()函数,接下来就方便了,将输入的数字拆分成3段来处理:

3.1 亿级

输入的数字范围是1~10000000000,因此需要对数字进行判断,如果长度是8位,才需要处理,对应的代码如下:

读数系统-第11届蓝桥杯国赛Python真题精选_第6张图片

代码比较好理解,简单说明4点:

1). 变量"res"用来表示最后的结果,也就是完整的拼音串,初始值设为空;

2). 如果字符串长度大于8,就截取亿级部分的数字串,这里使用了s[:-8]的编程技巧;

3). 获取亿级的拼音串后,在尾部增加单位"yi",注意左右各有一个空格;

4). 亿级处理完成,就删除亿级的数字串,并保存到变量"s"中。

3.2 万级

对于万级的处理和亿级基本类似,继续编写代码如下:

读数系统-第11届蓝桥杯国赛Python真题精选_第7张图片

由于万级的数字处在亿级和个级之间,有可能出现全0的情况,比如1200003456,这种情况下,万是不需要读的。

因此,这里做了一个判断,如果万级的4位不是全0,则需要读数,然后在末尾加上"wan",最后去掉万级,只保留各级的数字串。

3.3 个级

个级的情况比较简单,直接读取即可,继续编写代码如下:

读数系统-第11届蓝桥杯国赛Python真题精选_第8张图片

处理完亿级,万级和个级,去掉最后的空格,基本上就可以了。

4. 完善细节

到这里,基本上就可以处理大部分数据了,但是还有一个特殊的情况,就是万级数据全为0,个级有千位,比如1200003456,使用上面的程序,结果如下:

图片

很显然,这里少了一个"ling",所以,针对这种情况,需要单独处理,修改亿级代码如下:

读数系统-第11届蓝桥杯国赛Python真题精选_第9张图片

再次测试,效果如下:

图片

这一次,就没有问题了,注意,我们需要多测试一些数据,尤其是包含0的情况,下面这些是建议测试的数据:

1101001000100001000001000000100000001000000001000000001000000000
12123123412345123456123456712345678123456789123456789112345678912
10212010231203123010021020120010002100201020012000100002100020100200102000120000100000210000201000200100200010200001200000......

至此,整个程序就全部完成了,你也可以输入不同的数字来测试效果。

四.总结与思考

本题代码在35行左右,涉及到的知识点包括:

  • 循环语句,主要for...in循环;

  • 条件语句,包括单分支和双分支;

  • 字符串处理;

  • 列表的使用;

  • 函数的定义及使用;

作为国赛真题,本题难度较大,除了常见的Pytho基础知识外,更重要的是逻辑思维能力和解决问题的方法和能力。

对于任何一个复杂问题,我们都可以尝试运用计算思维对其进行拆分,将其拆分成若干简单问题,将简单问题一一解决了,复杂问题也就八九不离十了。

同时,要注意细节的把握和处理,对所有的情况都要做到不重复不遗漏。

超平老师给你留一道思考题,对于本题的测试数据,有没有好的办法,做到快速测试呢?

你还有什么好的想法和创意吗,也非常欢迎和超平老师分享探讨。

如果你觉得文章对你有帮助,别忘了点赞和转发,予人玫瑰,手有余香

需要源码的,可以移步至“超平的编程课”gzh。

你可能感兴趣的:(蓝桥杯,python,少儿编程竞赛,STEMA测评)