273. Integer to English Words - cocoder39/coco39_LC GitHub Wiki

273. Integer to English Words

LESS_THAN_TWITY = [
    '',
    'One',
    'Two',
    'Three',
    'Four',
    'Five',
    'Six',
    'Seven',
    'Eight',
    'Nine',
    'Ten',
    'Eleven',
    'Twelve',
    'Thirteen',
    'Fourteen',
    'Fifteen',
    'Sixteen',
    'Seventeen',
    'Eighteen',
    'Nineteen'
]

TEENS = [
    '',
    '',
    'Twenty',
    'Thirty',
    'Forty',
    'Fifty',
    'Sixty',
    'Seventy',
    'Eighty',
    'Ninety'
]

THOUSAND_WORDS = [
    'Billion',
    'Million',
    'Thousand',
    ''
]

THOUSAND_INTS = [
    10**9,
    10**6,
    10**3,
    10**0
]

class Solution:
    def numberToWords(self, num: int) -> str:
        if num == 0:
            return 'Zero'

        res = ''
        thouand_idx = 0
        for thouand_idx in range(4):
            thousand_int = THOUSAND_INTS[thouand_idx]
            thousand_word = THOUSAND_WORDS[thouand_idx]
            if num >= thousand_int:
                hundred = self.hundredToWords(num // thousand_int)

                # if there is existing content, inserting a space before adding new content
                if len(res) > 0: 
                    res += ' '
                res += hundred
                # before adding thousand word, inserting a space
                if len(res) > 0 and thouand_idx < 3: # no thousand word
                    res += ' '
                res += thousand_word
                num %= thousand_int
            thouand_idx += 1

        return res

    # convert a num within [0, 999] to words
    def hundredToWords(self, num: int) -> str:
        if num >= 1000:
            raise Exception('unexpected input {}', num)
        
        res = ''
        if num >= 100:
            res += LESS_THAN_TWITY[num // 100] + ' Hundred'
            num %= 100
        
        if num >= 20:
            if len(res) > 0:
                res += ' '
            res += TEENS[num // 10]
            num %= 10
        
        if num > 0:
            if len(res) > 0:
                res += ' '
            res += LESS_THAN_TWITY[num]
        return res

Notes 2022

class Solution:
    __less_than_20 = [
        '',
        'One',
        'Two',
        'Three',
        'Four',
        'Five',        
        'Six',
        'Seven',
        'Eight',
        'Nine',
        'Ten',
        'Eleven',
        'Twelve',
        'Thirteen',
        'Fourteen',
        'Fifteen',
        'Sixteen',
        'Seventeen',
        'Eighteen',
        'Nineteen'
    ]
    
    __tens = [
        'dummy',
        'dummy',
        'Twenty',
        'Thirty',
        'Forty',
        'Fifty',
        'Sixty',
        'Seventy',
        'Eighty',
        'Ninety'
    ]
    __thousands = ['', 'Thousand', 'Million', 'Billion']
    
    def numberToWords(self, num: int) -> str:
        if num == 0:
            return 'Zero'
        
        res = ''
        for t in Solution.__thousands:
            if num % 1000 != 0:
                res = self.hundredsToWords(num%1000) + t + ' ' + res
            num //= 1000
        return res.strip()
    
    def hundredsToWords(self, num: int) -> str:
        if num == 0: 
            return '' # no pending space if no word
        
        if num < 20:
            return Solution.__less_than_20[num] + ' ' # pending space if there is a word
        
        if num < 100:
            return Solution.__tens[num//10] + ' ' + self.hundredsToWords(num%10) # insert space because there is a word, let hundredsToWords handle pending space
        
        return Solution.__less_than_20[num//100] + ' Hundred ' + self.hundredsToWords(num%100)

=========================================================

How to read large numbers

class Solution {
public:
    string numberToWords(int num) {
        if (num == 0)   return "Zero";
        
        string res;
        int i = 0;
        /*
            i = 0, two trailing ' '
            i > 0, if res.empty(), one trailing ' ' behind THOUSANDS; else, trailing ' ' generated from i = 0
        */
        while (num > 0) {
            if (num % 1000) {
                //guarantee one trailing ' ' generated by helper()
                res = helper(num % 1000) + THOUSANDS[i] + " " + res;
            }
            num /= 1000;
            i++;
        }
        while (! res.empty() && res.back() == ' ')  res.pop_back();
        return res;
    }
private:
    const vector<string> LESS_THAN_20{"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", 
                       "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
    const vector<string> TENS{"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
    const vector<string> THOUSANDS{"", "Thousand", "Million", "Billion"};
    
    /*
        1. There has to be a ' ' behind "Hundred"
        2. when num is 100,200..., ' ' in case 1 is a trailing ' '
        3. add ' ' to the end of other cases for consistency
    */
    string helper(int num) { //0 <= num < 1000
        if (num == 0) {
            return "";
        } else if (num < 20) {
            return LESS_THAN_20[num] + " "; //consist with ' ' behind "Hundred"
        } else if (num < 100) {
            return TENS[num / 10] + " " + helper(num % 10); //consist with ' ' behind "Hundred"
        } else {
            return LESS_THAN_20[num / 100] + " Hundred " + helper(num % 100);
        } 
    }
};
⚠️ **GitHub.com Fallback** ⚠️