这绝对是个非常有趣的问题哈哈,但用python列表实现就变得比较烧脑,正常人不会非常较真这样的程序,我也只是闲来无事,如果代码还是有bug,那么我也没办法。
注:经过广泛搜索和仔细深究,似乎没有几套开源代码能100%满足要求
参考标准:大小写转换器_人民币大写在线转换工具
首先将一个数字根据小数点,进行分割。建立字典和数据集(left_chinese, right_chinese),这里left_chinese不加元,是因为后面可以统一处理,避免庸人自扰。
def Digital_to_Chinese(digital):
if not isinstance(digital, str): # 首先将内容转换为浮点数
str_digital = str(digital)
else:
str_digital = digital
print("小写数字", digital)
chinese = {'1': '壹', '2': '贰', '3': '叁',
'4': '肆', '5': '伍', '6': '陆',
'7': '柒', '8': '捌', '9': '玖', '0': '零'}
left_chinese = ['', '拾', '佰', '仟', '万'] # 小数点左边
right_chinese = ["角", "分"] # 小数点右边
left_Str, right_Str = "", "" # 根据小数点将浮点数分成整数小数两部分
if '.' in str_digital:
left_Str, right_Str = str_digital.split('.')
else:
left_Str = str_digital # 没有的话就直接都是整数部分
leftStrArr = [] # 处理整数部分
将左边数字从高位向低位读取,再翻转——即从低向高。之后,把每个数字对应的权重附在数字后面(empty, 拾, 佰, 仟, 万),同样的思路也适用于右半块数字。
if left_Str:
leftStrArr = [chinese[v] for v in left_Str] # 使用列表推导式获取大写中文列表
leftStrArr.reverse() # 由于数字是从前到后读,所以从低位向高位转换需要倒置列表
for i in range(0, len(leftStrArr)):
if leftStrArr[i] != "零": # 只要这一位不是0,就在后面赋值他对应的权重,如果为0则i自增1将其略过
leftStrArr[i] += left_chinese[i]
leftStrArr.reverse()
rightStrArr = [] # 处理小数部分
if right_Str:
rightStrArr = [chinese[v] for v in right_Str]
for i in range(0, len(rightStrArr)):
if rightStrArr[i] != "零":
rightStrArr[i] += right_chinese[i] # 和前面一样的道理
之后,我们需要进行二次处理,首先刚刚那样的算法会多输出0,比如 2001 会被写成 两仟零零壹,针对这个问题我们可以直接去重处理,这里注意,101是不会被去除的,因为那是[壹佰,零,壹],所以不会被去重。
但这并不完美,因为还会有这样的问题:10 会被写成 壹拾零,解决方法是判断末尾字符是否为零,是则删去不是则跳过。
此外,由于正常的计费只到“分”,所以右半部分正常情况下不需要过多的处理,因此代码就写完了。
leftStrArr_temp = []
for xleft in leftStrArr:
if xleft not in leftStrArr_temp: # 去重,防止出现 xx零零xx
leftStrArr_temp.append(xleft)
leftStrArr_temp.reverse()
for temp in leftStrArr_temp: # 去掉末尾的零
if temp == "零":
leftStrArr_temp.remove(temp)
else:
break
leftStrArr_temp.reverse()
print("------\n左", ''.join(leftStrArr_temp))
rightStrArr_temp = []
for xright in rightStrArr:
if xright not in rightStrArr_temp:
rightStrArr_temp.append(xright)
print("右", ''.join(rightStrArr_temp))
return ''.join(leftStrArr_temp) + "元" + ''.join(rightStrArr_temp) # 将列表合并成一个字符串,作为结果返回
# test = input("请输入测试用例:")
test_list = [1, 1.1, 11.01, 10.10, 10.01, 101.01, 2300.02, 34004.09]
for test in test_list:
print("结果", Digital_to_Chinese(test), "\n------\n")
这个测试应该没有问题,整数部分的高位可以直接加在列表中,低位部分各位可以自行完善。结果如下:
小写数字 | 左串 | 右串 | 结果 |
1 | 壹 | 空 | 壹元 |
1.1 | 壹 | 壹角 | 壹元壹角 |
11.01 | 壹拾壹 | 零壹分 | 壹拾壹元零壹分 |
10.1 | 壹拾 | 壹角 | 壹拾元壹角 |
10.01 | 壹拾 | 零壹分 | 壹拾元零壹分 |
101.01 | 壹佰零壹 | 零壹分 | 壹佰零壹元零壹分 |
2300.02 | 贰仟叁佰 | 零贰分 | 贰仟叁佰元零贰分 |
34004.09 | 叁万肆仟零肆 | 零玖分 | 叁万肆仟零肆元零玖分 |