?
可能有些情況沒有考慮到。
?
?
源碼?
python3:
#encoding=utf-8
import math
#系數(shù)
CN_NUM = {
'〇': 0,
'一': 1,
'二': 2,
'兩': 2,
'三': 3,
'四': 4,
'五': 5,
'六': 6,
'七': 7,
'八': 8,
'九': 9,
'零': 0,
}
#基數(shù)
CN_UNIT = {
'十': 10,
'百': 100,
'千': 1000,
'萬': 10000,
'億': 100000000,
}
#計(jì)算中文數(shù)字值,返回string
def calcCNNumberValue(digs):
if(not digs): return ""
#根據(jù)系數(shù)、基數(shù)map將漢字轉(zhuǎn)數(shù)值大小
tmp =[]
for d in digs[::-1]:
if(CN_NUM.__contains__(d)): tmp.append(CN_NUM[d])
elif(CN_UNIT.__contains__(d)): tmp.append(CN_UNIT[d])
#系數(shù)直接加入tmp2,基數(shù)相鄰相乘或者加入tmp2并在前面補(bǔ)1
tlen = len(tmp)
tmp2 = []
for i in range(0, tlen):
if(tmp[i] > 9):
if(i == tlen - 1 or tmp[i + 1] > tmp[i]):
tmp2.append(tmp[i])
tmp2.append(1)
elif(tmp[i + 1] > 9):
tmp[i + 1] *= tmp[i]
else: tmp2.append(tmp[i])
else: tmp2.append(tmp[i])
#系數(shù)直接加入seq,基數(shù)根據(jù)其大小用-1占住位置讓下一個(gè)系數(shù)在正確位上
seq = []
curW = 0
for t in tmp2:
if(t > 9):
w = math.log10(t)
while(curW < w):
curW += 1
seq.append(-1)
else:
curW += 1
seq.append(t)
#對(duì)于個(gè)位是非0的前方是-1的數(shù),要盡可能提到高位
if(seq[0] > 0 and len(seq) > 1 and seq[1] == -1):
seqLen, p = len(seq), 1
while(p < seqLen and seq[p] == -1): p += 1
#swap
seq[p - 1] = seq[0]
seq[0] = 0
#seq拼接,-1轉(zhuǎn)為0,其余的保持原數(shù)值
return "".join([str(n if n >= 0 else 0) for n in seq[::-1]])
#測(cè)試
if __name__ == '__main__':
print(calcCNNumberValue("零")) #0
print(calcCNNumberValue("五")) #5
print(calcCNNumberValue("十")) #10
print(calcCNNumberValue("一十")) #10
print(calcCNNumberValue("十五")) #15
print(calcCNNumberValue("三十五")) #35
print(calcCNNumberValue("三百五")) #350
print(calcCNNumberValue("三千五")) #3500
print(calcCNNumberValue("三千零五")) #3005
print(calcCNNumberValue("三千五十")) #3050
print(calcCNNumberValue("三千五百五")) #3550
print(calcCNNumberValue("二百萬")) #2000000
print(calcCNNumberValue("二百萬零五十")) #2000050
print(calcCNNumberValue("一萬一")) #11000
print(calcCNNumberValue("一萬一十")) #10010
print(calcCNNumberValue("一萬一百")) #10100
print(calcCNNumberValue("一萬一百一")) #10110
print(calcCNNumberValue("一萬一百零一")) #10101
print(calcCNNumberValue("一萬零一")) #10001
print(calcCNNumberValue("二〇一九")) #2019
print(calcCNNumberValue("千萬萬")) #100000000000
print(calcCNNumberValue("一千萬一")) #11000000
print(calcCNNumberValue("一千萬零一")) #10000001
?
說明
?
算法分幾步。
以幾個(gè)例子來說明。
?
第一步,將漢字轉(zhuǎn)為數(shù)值,在系數(shù)map和基數(shù)map中搜索,非法字符在這里會(huì)直接被過濾。digs倒著循環(huán),則原先數(shù)值的低位會(huì)存在tmp數(shù)組的低位中。
? 例如:
? ? “一百萬零六” ,轉(zhuǎn)換后存tmp中,tmp為: [6, 0, 10000, 100, 1]
? ? "一百十一“, ->? tmp : [1, 10, 100, 1]
? ? "一萬一",? ? ? ?->? tmp : [1, 10000, 1]
?
第二步,將基數(shù)加入tmp2并在前補(bǔ)1,或者和前基數(shù)合并,系數(shù)直接加入tmp2。(解決“十一”, “十”這種基數(shù)前沒系數(shù)的情況)
例如:
? ? “一百萬零六”? -> tmp2 :?[6, 0, 1000000, 1]? ? (10000 < 100,? 10000被乘到下一個(gè)100上并被丟棄)
? ? "一百十一“, ->? tmp2 : [1, 10, 1, 100, 1]? ? ? (10<100,10前補(bǔ)1)
? ? "一萬一",? ? ? ?->? tmp2 : [1, 10000, 1]
?
第三步,基數(shù)變現(xiàn),基數(shù)的存在是為了下一個(gè)系數(shù)能夠在正確的位置上。遇到系數(shù),直接丟入seq,遇到基數(shù),丟棄或者,在中間補(bǔ)位 (此處補(bǔ)-1,為了和“零”作區(qū)別),讓下一個(gè)系數(shù)位置符合這個(gè)基數(shù)的描述。
例如:
? ? “一百萬零六” ->? seq :?[6, 0, -1, -1, -1, -1, 1]? ? (1000000取log是6,下一個(gè)系數(shù)必須在第6+1位上(第一個(gè)是第1位),中間補(bǔ)-1,直到當(dāng)前seq長度為6)
? ? "一百十一“, ->? seq : [1, 1, 1]? ? ? (10取log是1,直接丟棄,100取log是2,直接丟棄)
? ? "一萬一",? ? ? ?->? seq : [1, -1, -1, -1, 1]? ?(10000取log是4,中間補(bǔ)-1,直到當(dāng)前seq長度為4,下一個(gè)1插到第5位上,表示“萬”)
?
第四步,最低位非零數(shù)字滿足條件可升高位,前面補(bǔ)-1而不補(bǔ)0的作用在此體現(xiàn)。(針對(duì),一萬二,兩百二等情況,最低位的“二”應(yīng)分別指代“二千”和“二十”,要盡可能往上升高位)
例如:
? ? ?“一百萬零六”? ->? seq :?[6, 0, -1, -1, -1, -1, 1]? ? (最低為6緊挨著0,說明中文描述時(shí)指定了“零”,不做處理)
? ? ? "一百十一“, ->? seq : [1, 1, 1]? ? ? (最低為1,相鄰1,不做處理)
? ? ? "一萬一",? ? ? ?->? seq : [-1, -1, -1, 1, 1]? (最低位1,相鄰著-1,則向高位找,直到非-1為止,找到第4位(第一個(gè)算第1位),將第1個(gè)和第4個(gè)數(shù)值交換,“1”由個(gè)位升至千位)
?
第五步,seq倒過來轉(zhuǎn)為string。seq地位存數(shù)值地位,所以低位要放右側(cè),倒著循環(huán)。-1變成0,不小于0的保留原值。
例如:
? ? ? “一百萬零六”? -> return :?1000006??
? ? ? "一百十一“,? ->? return : 111?
? ? ? "一萬一",? ? ? ?->? return : 11000?
?
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
