题目描述:
银行在打印票据的时候,常常需要将阿拉伯数字表示的人民币金额转换为大写表示,现在请你来完成这样一个程序。
在中文大写方式中,0到10以及100、1000、10000被依次表示为: 零 壹 贰 叁 肆 伍 陆 柒 捌 玖 拾 佰 仟 万
以下的例子示范了阿拉伯数字到人民币大写的转换规则:
1 壹圆
11 壹拾壹圆
111 壹佰壹拾壹圆
101 壹佰零壹圆
-1000 负壹仟圆
1234567 壹佰贰拾叁万肆仟伍佰陆拾柒圆
现在给你一个整数a( | a | <100000000), 请你打印出人民币大写表示. |
例如:a=1
则输出:壹圆
注意:请以Unicode的形式输出答案。提示:所有的中文字符,在代码中直接使用其Unicode的形式即可满足要求,中文的Unicode编码可以通过如下方式获得:u’壹’。
注意:代码无需声明编码!!不要在代码头部声明文件编码,否则会导致语法错误!
分析
我分析了一下,我这个就有点点考验细心的问题了。题目不难,就是需要考虑到比较多的情况。我用了很长时间才写完代码,写的很丑。但是运气好,直接 1A 了。
对于每1个数字都有下面的一些特性。
- 负数可以变成正数。
- 因为 |a|<100000000, 所以最大 8 个 9. 而这 8 位数字的数位是确定的。 如果用 百万 仟万 那么这个 万 很可能就会重复很多次,所以不记录。 pos = [‘仟’, ‘佰’, ‘拾’, ‘万’, ‘仟’, ‘佰’, ‘拾’, ‘圆’]
- 对于最大8个9,可以分为两个部分,万元以上,万元以下。 例如: 12345678 = 1234,5678
- 前面连续的零应该去掉。 例如: 00091234 == 9,1234
- 中间连续的零只保留一个。70011234 = 七仟零壹万, 壹仟贰佰叁拾肆 圆
- 没有零万,零仟,零佰的说法。 零圆 是一个特殊的存在。
因为有 0 ~ 9 个数字,所以需要一个数组专门存储一下。 然后 直接取下标就好。
nums = [‘零’, ‘壹’, ‘贰’, ‘叁’, ‘肆’, ‘伍’, ‘陆’, ‘柒’, ‘捌’, ‘玖’]
那么我们的问题就变得稍微明了。
- 如果是负数,就变为正数。
- 把每一位上面的数都一一映射为中文。如果为 0 就不要加 数位。因为没有 零仟,零佰的说法。
- 再特殊处理,下标为3和7的数。 因为上一步 为 0 的时候就不加数位。但是如果 超过万元以上,我们要有 “万” ,最后要有 “圆”。所以就把下标3位置的0改为 “万”, 下标7位置的0改为 “圆”
- 然后我们处理一下前导0,把前面的0都删除掉。
- 然后再把 连续的 0 去掉。方法: 如果当前位上是0,那就判断前一位是不是0,如果前一位不是0,那就保留,如果前一位也是0,那就去掉当前这个0.
- 这样我们最后得到的字符串就可能出现 “零万” 或者 “零圆” 的情况,我们再最后处理一下就好了。
我感觉我这样,干巴巴的说就很奇怪。感觉我是一个傻子。虽然我确实有点傻,但是我不会承认的。 我举一个栗子说明一下。
-100,0010 这个怎么读? 懂的懂,那就是: 负壹佰万零壹拾圆 。
开始了。
第一步: 负数变正数,我就不多 BB 了。
第二步:做一个 一一映射,如果是0 就不加数位 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | :—: | :—: | :—: | :—: | :—: | :—: | :—: | :—: | | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | | 零 | 壹佰| 零 | 零 | 零 | 零 | 壹拾 | 零 |
第三步: 下标3 还有 7 的位置 需要改变,加 “万” 和 “圆” | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | :—: | :—: | :—: | :—: | :—: | :—: | :—: | :—: | | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | | 零 | 壹佰| 零 | 万 | 零 | 零 | 壹拾 | 圆|
第四步:把连续的前导0删除掉,中间有一条线还加粗就是删除。 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | :—: | :—: | :—: | :—: | :—: | :—: | :—: | :—: | | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | | 零 | 壹佰| 零 | 万 | 零 | 零 | 壹拾 | 圆|
第五步: 把连续的 0 去掉。注意应该是删除位置5的0, 而不是位置4的0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | :—: | :—: | :—: | :—: | :—: | :—: | :—: | :—: | | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | | 零 | 壹佰| 零 | 万 | 零 | 零 | 壹拾 | 圆|
这一步会得到一个字符串: 壹佰零万零壹拾圆
第六步:把 “零万” 替换 “万”; 壹佰零万零壹拾圆 ==> 壹佰万零壹拾圆
这如果看不懂,那我就真的是个傻子了。
nums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
pos = ['仟', '佰', '拾', '万', '仟', '佰', '拾', '圆']
ta = a
step = ['零', '零', '零', '零', '零', '零', '零', '零']
i = -1
# 第一步 处理负数
if ta < 0:
res = "负"
ta = -ta
a = ta
else:
a = ta
res = ""
# 第二步 转换数位
while a:
step[i] = nums[a%10]
if step[i] != '零':
step[i] += pos[i]
a //= 10
i -= 1
# 第三步 处理特殊数位
if step[3] == '零' and ta > 10000:
step[3] = '万'
if step[7] == '零':
step[7] = '圆'
# 第四步 去掉前导0
step_2 = ""
for i in range(0, len(step)):
if step[i] == '零':
step_2 = step[i+1:]
else:
step_2 = step[i:]
break
step = step_2
# 第五步 去掉连续0
for key, value in enumerate(step):
if value[0] != '零':
res += value
else:
if value[0] != step[key-1][0]:
res += '零'
# 第六步 处理 '零圆' '零万' 的情况
res = res.replace('零圆', '圆')
res = res.replace('零万', '万')
if ta == 0:
res = "零圆"
print(res)