Leetcode 8. String to Integer (atoi) with - 리뷰 O

Alpha, Orderly·2023년 1월 16일

leetcode

목록 보기
30/218
post-thumbnail

문제

myAtoi(string s) 함수를 구현하세요. 이 함수는 문자열을 32비트 부호 있는 정수(32-bit signed integer) 로 변환합니다.

myAtoi(string s)의 동작 방식은 다음과 같습니다.

  1. 공백(Whitespace)
    문자열 앞부분에 있는 공백 문자 " "를 모두 무시합니다.

  2. 부호 확인(Signedness)
    다음 문자가 '-' 또는 '+'인지 확인하여 부호를 결정합니다.
    둘 다 아니라면 양수로 간주합니다.

  3. 숫자 변환(Conversion)
    앞에 있는 0들을 건너뛰면서 숫자를 읽기 시작합니다.
    숫자가 아닌 문자를 만나거나 문자열의 끝에 도달하면 읽기를 중단합니다.
    읽은 숫자가 하나도 없다면 결과는 0입니다.

  4. 범위 제한(Rounding)
    변환된 정수가 32비트 부호 있는 정수의 범위인

    [-2^31, 2^31 - 1]

    을 벗어나는 경우, 해당 범위 안으로 값을 제한합니다.

    구체적으로:

    • -2^31보다 작은 값은 -2^31로 처리합니다.
    • 2^31 - 1보다 큰 값은 2^31 - 1로 처리합니다.
  5. 최종적으로 변환된 정수를 반환합니다.

예시

Input: s = "42"
Output: 42

Input: s = "   -42"
Output: -42

Input: s = "4193 with words"
Output: 4193

Input: s = "+"
Output: 0

Input: s = "word 123"
Output: 0

Input: s = "+-12"
Output: 0

풀이

평범한 파싱 문제인데

문제는 Input이 너무 다양합니다.

그래서 파싱을 할수 있을만한 입력이 들어왔을때 동작만 구현하고

나머지는 try / except 를 통해 0을 리턴하도록 구현했습니다.

class Solution:
    def myAtoi(self, s: str) -> int:
        try:
            if s == "": return 0

            s = s.strip(" ")

            front = 0
            end = len(s)-1
            fv = [chr(x) for x in range(48, 58)] + ['+', '-']
            ev = [chr(x) for x in range(48, 58)]

            while s[front] not in fv:
                return 0
            while s[end] not in ev:
                end -= 1
            s = s[front:end+1]

            ch = ''

            idx = 0

            while s[idx] == '+' or s[idx] == '-':
                ch = s[idx] + ch
                idx += 1

            if idx == len(s): return 0

            if idx > 1: return 0

            while idx < len(s) and s[idx] in ev:
                ch = ch + s[idx]
                idx += 1

            ans = int(ch)

            if ans < -2**31: return -2**31
            if ans > 2**31-1 : return 2**31-1
            return ans
        except:
            return 0
            

리뷰

  • StateMachine을 사용해봤습니다.
class StateMachine:
    def __init__(self):
        self.state: Union['Init', 'Number', 'Dead'] = 'Init'
        self.value: int = 0
        self.sign: int = 1

    def transition(self, ch: str):
        if self.state == 'Init':
            if ch == '+':
                self.state = 'Number'
            elif ch == '-':
                self.sign *= -1
                self.state = 'Number'
            elif ch.isnumeric():
                self.value *= 10
                self.value += int(ch)
                self.state = 'Number'
            else:
                self.state = 'Dead'
        else:
            if ch.isnumeric():
                self.value *= 10
                self.value += int(ch)
            else:
                self.state = 'Dead'

    def getInteger(self):
        value = self.value * self.sign

        if value < -(2 ** 31):
            return -(2 ** 31)
        if value > 2 ** 31 - 1:
            return 2 ** 31 - 1

        return value

class Solution:
    def myAtoi(self, s: str) -> int:
        s = s.strip()
        m = StateMachine()

        for ch in s:
            m.transition(ch)
            if m.state == 'Dead':
                break

        return m.getInteger()
profile
만능 컴덕후 겸 번지 팬

0개의 댓글