리트코드 알고리즘/리트코드 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]
해당 계산 과정을 거치면, 결국 "숫자 하나 남은 리스트"를 얻게 된다. 하지만, 문제가 원하는 답은 숫자 하나이기에, 해당 요소 하나만 반환하면 된다.