Posts pythonTip 16 人民币金额打印
Post
Cancel

pythonTip 16 人民币金额打印

题目描述:

银行在打印票据的时候,常常需要将阿拉伯数字表示的人民币金额转换为大写表示,现在请你来完成这样一个程序。

在中文大写方式中,0到10以及100、1000、10000被依次表示为: 零 壹 贰 叁 肆 伍 陆 柒 捌 玖 拾 佰 仟 万

以下的例子示范了阿拉伯数字到人民币大写的转换规则:

1 壹圆

11 壹拾壹圆

111 壹佰壹拾壹圆

101 壹佰零壹圆

-1000 负壹仟圆

1234567 壹佰贰拾叁万肆仟伍佰陆拾柒圆

现在给你一个整数a(a<100000000), 请你打印出人民币大写表示.

例如:a=1

则输出:壹圆

注意:请以Unicode的形式输出答案。提示:所有的中文字符,在代码中直接使用其Unicode的形式即可满足要求,中文的Unicode编码可以通过如下方式获得:u’壹’。

注意:代码无需声明编码!!不要在代码头部声明文件编码,否则会导致语法错误!

分析

我分析了一下,我这个就有点点考验细心的问题了。题目不难,就是需要考虑到比较多的情况。我用了很长时间才写完代码,写的很丑。但是运气好,直接 1A 了。

对于每1个数字都有下面的一些特性。

  1. 负数可以变成正数。
  2. 因为 |a|<100000000, 所以最大 8 个 9. 而这 8 位数字的数位是确定的。 如果用 百万 仟万 那么这个 万 很可能就会重复很多次,所以不记录。 pos = [‘仟’, ‘佰’, ‘拾’, ‘万’, ‘仟’, ‘佰’, ‘拾’, ‘圆’]
  3. 对于最大8个9,可以分为两个部分,万元以上,万元以下。 例如: 12345678 = 1234,5678
  4. 前面连续的零应该去掉。 例如: 00091234 == 9,1234
  5. 中间连续的零只保留一个。70011234 = 七仟零壹万, 壹仟贰佰叁拾肆 圆
  6. 没有零万,零仟,零佰的说法。 零圆 是一个特殊的存在。

因为有 0 ~ 9 个数字,所以需要一个数组专门存储一下。 然后 直接取下标就好。

nums = [‘零’, ‘壹’, ‘贰’, ‘叁’, ‘肆’, ‘伍’, ‘陆’, ‘柒’, ‘捌’, ‘玖’]

那么我们的问题就变得稍微明了。

  1. 如果是负数,就变为正数。
  2. 把每一位上面的数都一一映射为中文。如果为 0 就不要加 数位。因为没有 零仟,零佰的说法。
  3. 再特殊处理,下标为3和7的数。 因为上一步 为 0 的时候就不加数位。但是如果 超过万元以上,我们要有 “万” ,最后要有 “圆”。所以就把下标3位置的0改为 “万”, 下标7位置的0改为 “圆”
  4. 然后我们处理一下前导0,把前面的0都删除掉。
  5. 然后再把 连续的 0 去掉。方法: 如果当前位上是0,那就判断前一位是不是0,如果前一位不是0,那就保留,如果前一位也是0,那就去掉当前这个0.
  6. 这样我们最后得到的字符串就可能出现 “零万” 或者 “零圆” 的情况,我们再最后处理一下就好了。

我感觉我这样,干巴巴的说就很奇怪。感觉我是一个傻子。虽然我确实有点傻,但是我不会承认的。 我举一个栗子说明一下。

-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)

This post is licensed under CC BY 4.0 by the author.
Trending Tags
Contents

pythonTip 15 大小写转换

pythonTip 17 公约数的个数

Trending Tags