Microsoft China Interview Question, 中文转换数字, Chinese word to Integer, Python easy to understand

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
	
Comments (1)