分析发现,中国的数字习惯是 4 位一节的,一个 4 位的数字可被转成几千几百几十几,至于后面添加什么单位则不确定:
如果这节 4 位数字出现在 1~4 位,则后面添加单位“元”;
如果这节 4 位数字出现在 5~8 位,则后面添加单位“万”;
如果这节 4 位数字出现在 9~12 位,则后面添加单位“亿”;
多于 12 位就暂不考虑了。
一些特殊情况需要注意:
class NumberToHanzi():
def __init__(self):
self.han_list = ["零" , "一" , "二" , "三" , "四" , "五" , "六" , "七" , "八" , "九"]
self.unit_list = ["十" , "百" , "千"]
'''
把一个四位的数字字符串变成汉字字符串
num_str 需要被转换的四位的数字字符串
返回四位的数字字符串被转换成汉字字符串
'''
def four_to_hanstr(self,num_str):
result = ""
num_len = len(num_str)
for i in range(num_len):
num = int(num_str[i])
if i != num_len - 1 and num != 0 :
result += self.han_list[num] + self.unit_list[num_len - 2 - i]
else :
if num == 0 and result and result[-1]=='零':
continue
else:
result += self.han_list[num]
return result
def dig2cn(self,num_str):
str_len = len(num_str)
if str_len > 12 :
print('数字太大,翻译不了')
return
# 如果大于8位,包含单位亿
elif str_len > 8:
hanstr = self.four_to_hanstr(num_str[:-8]) + "亿" + \
self.four_to_hanstr(num_str[-8: -4]) + "万" + \
self.four_to_hanstr(num_str[-4:])
# 如果大于4位,包含单位万
elif str_len > 4:
hanstr = self.four_to_hanstr(num_str[:-4]) + "万" + \
self.four_to_hanstr(num_str[-4:])
else:
hanstr = self.four_to_hanstr(num_str)
if hanstr[-1]=='零':
hanstr = hanstr[:-1]
return hanstr
num = '50050000'
nth = NumberToHanzi()
ans = nth.dig2cn(num)
print(ans)
同样基于中国数字4 位一节的习惯,从后往前读取数字,遇到“个”“十”“百”“千”的直接将前一个数字(即下一个pop出来的数字)乘以位数,先写到一个临时数组里;遇到逢4的位,即“万”“亿”“兆”这种,把单位写进临时数组,最后再统一读出数组,进行累加。
同样有一些特殊情况需要注意:
CN_NUM = {
u'〇': 0,
u'一': 1,
u'二': 2,
u'三': 3,
u'四': 4,
u'五': 5,
u'六': 6,
u'七': 7,
u'八': 8,
u'九': 9,
u'零': 0,
u'壹': 1,
u'贰': 2,
u'叁': 3,
u'肆': 4,
u'伍': 5,
u'陆': 6,
u'柒': 7,
u'捌': 8,
u'玖': 9,
u'貮': 2,
u'两': 2,
}
CN_UNIT = {
u'十': 10,
u'拾': 10,
u'百': 100,
u'佰': 100,
u'千': 1000,
u'仟': 1000,
u'万': 10000,
u'萬': 10000,
u'亿': 100000000,
u'億': 100000000,
u'兆': 1000000000000,
}
def cn2digTransformer(cn):
lcn = list(cn)
unit = 0 # 当前的单位
ldig = [] # 临时数组
ret = 0
tmp = 0
if lcn[-2:]==['零', '十']: # “一千零十”
ret = 10
lcn = lcn[:-2]
while lcn:
cndig = lcn.pop()
if cndig in CN_UNIT: # python2: CN_UNIT.has_key(cndig)
unit = CN_UNIT.get(cndig)
if unit == 10000:
ldig.append('w') # 标示万位
unit = 1
elif unit == 100000000:
ldig.append('y') # 标示亿位
unit = 1
elif unit == 1000000000000: # 标示兆位
ldig.append('z')
unit = 1
continue
else:
dig = CN_NUM.get(cndig)
if dig == None:
return False
else:
if unit:
dig = dig * unit
if len(ldig)==1 and isinstance(ldig[0],int) and ldig[0]<10: # “七百五”“七千五”的“五”不是个位
ldig[0] = ldig[0]*unit//10
if len(ldig)==2 and isinstance(ldig[0],int) and ldig[0]<10: # “七亿五”“七万五”的“五”不是个位
if ldig[-1]=='w':
ldig[0] = ldig[0] * 1000
elif ldig[-1]=='y':
ldig[0] = ldig[0] * 10000000
elif ldig[-1]=='z':
ldig[0] = ldig[0] * 100000000000
unit = 0
ldig.append(dig)
if unit == 10: # 处理10-19的数字
ldig.append(10)
while ldig:
x = ldig.pop()
if x == 'w':
tmp *= 10000
ret += tmp
tmp = 0
elif x == 'y':
tmp *= 100000000
ret += tmp
tmp = 0
elif x == 'z':
tmp *= 1000000000000
ret += tmp
tmp = 0
else:
tmp += x
ret += tmp
return str(ret)
while 1:
x = input()
print(cn2digTransformer(x))
参考网址:
Python项目实战:数字转人民币读法
Python将汉字数字转换成阿拉伯数字的方法