리트코드 알고리즘/리트코드 medium

(간단한 코드)리트코드 150. Evaluate Reverse Polish Notation

문학적 딥러닝 2024. 12. 19. 20:51

 

숫자는 그냥 리스트에 넣고, "기호"가 들어오면, "앞의 숫자"와 "앞의앞 숫자"와 계산을 하면 되는 이해하기 쉬운 문제다.

 

이 문제는 노가다를 하면 된다(실제로는 대부분 같은 코드를 복붙하면 된다)

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        ans = []

        for t in tokens:
            if t == '+':
                cur = ans.pop() #중복
                pre = ans.pop() #중복
                ans.append(pre + cur)
            elif t == '-':
                cur = ans.pop() #중복
                pre = ans.pop() #중복
                ans.append(pre - cur)
            elif t == '*':
                cur = ans.pop() #중복
                pre = ans.pop() #중복
                ans.append(pre * cur)
            elif t == '/':
                cur = ans.pop() #중복
                pre = ans.pop() #중복
                div = pre / cur
                ans.append(int(div))
            else:
                ans.append(int(t))
        return ans[0]

 

여기서 알아야 할 것은, 리스트에 pop()를 사용하면, "맨 마지막에 있는 숫자를 복사가 아니가 꺼내온다"는 것을 사용한다.

여기서 cur -> 가장 마지막 숫자, pre -> 뒤에서 두번째 숫자 라는 것을 알아야 한다.

 

여기서는 "중복되는 코드"가 많이 보인다. 이는 다음과 같이 정리할 수 있다.

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        ans = []

        for t in tokens:
            if t in '+-*/':
            	cur = ans.pop()
                pre = ans.pop()
                if t == '+':
                    ans.append(pre + cur)
                elif t == '-':
                    ans.append(pre - cur)
                elif t == '*':
                    ans.append(pre * cur)
                elif t == '/':
                    div = pre / cur 
                    ans.append(int(div)) # 설명(1)
             else:
             	ans.append(int(t)) #설명(2)
         return ans[0] # 설명(3)

 

여기서 설명을 해야 하는 점 4가지를 하겠다.

설명(1) ans.append(int(div))

본래 문제는 나누기를 할 때 "몫"만 출력 하도록 설정이 되어 있으므로, 그냥 '/'가 아니라 '//'를 사용해야 하지만

파이썬 나누기에는 다음과 같은 문제가 있다.

69 // (-61)
>>> -2 #-1이 나와야 함
6 // -10
>>> -1 #0이 나와야 함

 

이렇게 나오는 이유는 '//'에는 결과물을 비교적 작은 쪽의 integer(정수)를 출력하므로, 소수점 자리의 수를 버린다.

12 // 7 #//는 정수를 출력한다
>>> 1 #1.6... 가 나오는데, 이를 1과 2중에 더 작은 1을 출력

 

이 기능이 0 이하의 숫자(음수)가 나왔을 때, 더 작은 숫자로 내리기 때문이다.

69 // (-61)
>>> -1.1311... 보다 작은 "정수"는 -2
>>> -2 출력

6 // -10
>>> -0.6 보다 작은 "정수"는 -1
>>> -1 출력

 

따라서 div = pre / cur을 하면 소수점을 포함한 숫자가 나오고, 이를 int()로 감싸서 소수점을 버리는 형식으로 취해주는 것이다.

 

설명(2) ans.append(int(t))

이 부분은 숫자가 나왔을 때, 실제로 받은 값은 '4' -> 문자열 형식 이므로. int()를 씌워줘야 한다.

 

설명(3) ans[0]

해당 계산 과정을 거치면, 결국 "숫자 하나 남은 리스트"를 얻게 된다. 하지만, 문제가 원하는 답은 숫자 하나이기에, 해당 요소 하나만 반환하면 된다.