It is a commonly asked question for chinese Tech companies, similar to English to Integer but chinese number is grammatically simpler than english words.
class ParseWord:
def __init__(self):
self.num_map = {'一': 1, '二': 2, '三': 3, '四': 4, '五': 5, '六': 6, '七': 7, '八': 8, '九': 9}
self.unit_map = {'十': 10, '百': 100, '千': 1000, '万': 10000, '亿': 100000000}
def chineseWordsToInt(self, word: str) -> int:
"""
transform a chinese word to integer
"""
word = word.replace('零', '') # remove all 零(0) that will interrupt the parsing
num = self.divide(word)
return num
def divide(self, word: str) -> int:
"""
split chinese word to billion part and ten thousands part
"""
if not word: # since we removed all 零(0), then empty string meaning 0
return 0
n = len(word)
billion_idx, ten_thous_idx = -1, -1
for i in range(n):
if word[i] == '亿':
billion_idx = i
if word[i] == '万':
ten_thous_idx = i
# handle number that is larger than billion
if billion_idx != -1:
return self.conquer(word[:billion_idx]) * self.unit_map['亿'] + self.divide(word[billion_idx + 1:])
# handle number that is larger than ten thousands
elif ten_thous_idx != -1:
return self.conquer(word[:ten_thous_idx]) * self.unit_map['万'] + self.divide(word[ten_thous_idx + 1:])
# handle number tha is smaller than ten thousands
return self.conquer(word[ten_thous_idx + 1:])
def conquer(self, word: str):
"""
handle chinese words that is smaller than then thousands
"""
num = 0
thou_idx, hun_idx, ten_idx = -1, -1, -1
n = len(word)
for i in range(n):
if word[i] == '千':
thou_idx = i
if word[i] == '百':
hun_idx = i
if word[i] == '十':
ten_idx = i
if thou_idx != -1:
num += self.num_map[word[thou_idx - 1]] * self.unit_map['千']
if hun_idx != -1:
num += self.num_map[word[hun_idx - 1]] * self.unit_map['百']
if ten_idx != -1:
num += self.num_map[word[ten_idx - 1]] * self.unit_map['十']
# handle the last single digit, if exist
if word[-1] not in self.unit_map:
num += self.num_map[word[-1]]
return num
if __name__ == "__main__":
s = ParseWord()
assert s.chineseWordsToInt("一亿五千六百零八十二") == 100005682
assert s.chineseWordsToInt("零") == 0
assert s.chineseWordsToInt("二十三") == 23
assert s.chineseWordsToInt("三") == 3
assert s.chineseWordsToInt("六千七百万零八百二十三") == 67000823