본문 바로가기

코드 이야기

[LeetCode] String to Integer (atoi) - medium level

 LeetCode medium level 문제이지만 medium 치고는 그리 어렵지 않은 문제로 비교적 간단하게 풀이 가능한 문제입니다.

문제: 문자열을 숫자로 변환하는 atoi 함수 구현

□ Example 1:
   - Input: "42"
   - Output: 42

 Example 2:
   - Input: " -42"
   - Output: -42
   - Explanation: The first non-whitespace character is '-', which is the minus sign.   Then take as many numerical digits as possible, which gets 42.

 Example 3:
   - Input: "4193 with words"
   - Output: 4193
   - Explanation: Conversion stops at digit '3' as the next character is not a numerical digit.

 Example 4:
   - Input: "words and 987"
   - Output: 0
   - Explanation: The first non-whitespace character is 'w', which is not a numerical   digit or a +/- sign. Therefore no valid conversion could be performed.

 Example 5:
   - Input: "-91283472332"
   - Output: -2147483648
   - Explanation: The number "-91283472332" is out of the range of a 32-bit signed integer.   Thefore INT_MIN (−231) is returned.

 

 풀이
   1. 왼쪽의 문자열이 공백으로 시작되는 경우는 무시한다.
   2. - 혹은 + 로 시작되면 숫자가 부호를 반영한다.
   3. 문자로 시작하면 0이다.
   4. 숫자로 시작하다가 문자가 나타나면 숫자부분만 숫자로 변환한다.
   5. 32-bit signed integer 의 범위를 벗어나는 숫자는 32-bit signed integer의 최대 혹은 최소값을 반환한다. 최대값: (2^31)-1, 최소값: 2^31

class Solution:
    def myAtoi(self, str: str) -> int:
    	# 왼쪽의 공백을 처리
        num = str.lstrip()
        size = len(num)
        if size < 1:
            return 0
        
        neg = False
        nPos = 0
        # 숫자의 부호를 처리
        if num[nPos] == '-':
            neg = True
            nPos += 1
        elif num[nPos] == '+':
            nPos += 1
            
        ans = 0
        while nPos < size:
        	# 숫자가 아닌 경우 멈춤
            # isdigit을 쓰지 못하는 경우 ASCII 코드값을 이용
            # ord('1') 하면 49 반환
            # if (ord(num[nPos]) > 48 and ord(num[nPos]) < 58 인 경우 digit임
            if num[nPos].isdigit() == False:
                break
            
            # 자리수가 커지는 계산을 아래와 같이 함
            # int 함수를 쓰지 못하는 경우에는 ASCII 코드값을 가지고 계산
            # 문자 '1'의 ASCII 값이 49이므로 '1'-48로 계산
            ans = ans * 10 + int(num[nPos])
            nPos += 1
            
        # 음수인 경우 계산, math.pow(2, 31), 2**31 처럼 계산가능
        # 아래는 bitwise를 이용, 1비트를 31만큼 왼쪽으로 옮기는 값이 결국 2**31과 같음을 이용
        if neg == True:
            ans = min (1<<31, ans)
            ans = ans * -1
        else:
            ans = min ((1<<31)-1, ans)    
            
        return ans