1. 程式人生 > >4.2.3 LeetCode字串類題目選做(3) —— String to Integer (atoi) & Integer to English Words

4.2.3 LeetCode字串類題目選做(3) —— String to Integer (atoi) & Integer to English Words

這一節是關於字串和數字的解析的兩個題目,往往要求我們不要用內建的型別轉換函式。

8. String to Integer (atoi)

Implement atoi which converts a string to an integer.

具體要求簡述:字串開始可以有多個空格,然後是可能有的+/-號以及多個數字,如" -42",解析為對應的數字。

注意的是:數字後,可以有其他字元,可以忽略,如"4193 with words";如果第一個非空字元不符合條件,或者字串中沒有可解析的數字等,返回0,如"words and 987";最後,如果解析的數字超出int值範圍,返回對應的上限/下限。

題目解析:

認真分析上述限制條件,將各種情況處理好即可;注意的是數字字元的解析用ord函式。程式碼如下:

class Solution:
    def myAtoi(self, strs):
        """
        :type str: str
        :rtype: int
        """
        flag = 1
        sign = 0
        num = 0
        for char in strs:
            if flag:
                if char == ' ':
                    continue
                elif char == '-' or char == '+':
                    sign = 1 if char == '-' else 0
                    flag = 0
                
                elif 0 <= ord(char) - ord('0') < 10:
                    flag = 0
                    num = ord(char) - ord('0')
                else:
                    return 0
            else:
                if 0 <= ord(char) - ord('0') < 10:
                    num = num * 10 + ord(char) - ord('0')
                else:
                    break
        ret = -num if sign else num
        maxint = pow(2, 31) -1
        minint = -pow(2, 31)
        if ret > maxint:
            return maxint
        elif ret < minint:
            return minint
        else:
            return ret

273. Integer to English Words

Convert a non-negative integer to its english words representation. Given input is guaranteed to be less than 2^31 - 1.

Input: 1234567
Output: "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"

題目解析:

這一題難度是hard,但是並不難做。2^31是四十多億,從右向左將數字三個為一組,讀出這個1-3位數(不超過1000),然後在後面加上’單位‘,單位依次是 ‘’, ‘thousand’, ‘million', 'billion';基本原理是這樣。

還有許多細節問題,一是十幾(eleven等),十位數為1時單獨處理,二是拼接各部分時空格連線的邏輯,我也沒完全處理好。程式碼如下,可以看出最難寫的read這一模組:

class Solution:
    def numberToWords(self, num):
        """
        :type num: int
        :rtype: str
        """
        end = ["", "Thousand", "Million", "Billion", ]
        dig1 = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"]
        dig2 = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"]
        dig3 = ["Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"]
        def get_read(num):
            num, m = divmod(num, 10)   # m 個位數
            num, n = divmod(num, 10)   # n 十位數 
            
            if num:
                string = dig1[num] + " Hundred"
            else:
                string = ""
            if n == 0:
                if m == 0:
                    pass
                else:
                    if string:
                        string = string + ' ' + dig1[m]
                    else:
                        string += dig1[m]
            elif n == 1:
                if string:
                    string = string + ' ' + dig3[m]
                else:
                    string += dig3[m]                    
            else:
                if string:
                    string = string + ' ' + dig2[n] + ' ' + dig1[m]
                else:
                    string += dig2[n] + ' ' + dig1[m]
                        
            return string.strip()          
                        
        if num == 0:
            return "Zero"
        l = len(str(num))
        div = 1000
        ret = ""
        
        cn = -1
        while num:
            num, m = divmod(num, div)
            cn += 1
            if not m:
                continue
            read = get_read(m)            
            ret = read +' '+ end[cn] + ' ' + ret
            
        
        return ret.strip()

歐克,對於字串的一些基本的解析/處理的題目就到此了。後面會有更多有主題/有演算法思想應用的題目。