Basic Calculator
Given a string s
representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation.
Note: You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval()
.
Example 1:
Input: s = "1 + 1"
Output: 2
Example 2:
Input: s = " 2-1 + 2 "
Output: 3
Example 3:
Input: s = "(1+(4+5+2)-3)+(6+8)"
Output: 23
Constraints:
1 <= s.length <= 3 * 105
s
consists of digits,'+'
,'-'
,'('
,')'
, and' '
.s
represents a valid expression.'+'
is not used as a unary operation (i.e.,"+1"
and"+(2 + 3)"
is invalid).'-'
could be used as a unary operation (i.e.,"-1"
and"-(2 + 3)"
is valid).- There will be no two consecutive operators in the input.
- Every number and running calculation will fit in a signed 32-bit integer.
class Solution:
def calculate(self, s: str) -> int:
ans = 0
num = 0
sign = 1
stack = [sign]
for i in s :
if i.isdigit() :
num = num * 10 + int(i)
elif i == '(' :
stack.append(sign)
elif i == ')' :
stack.pop()
elif i == '+' or i == '-' :
ans += sign * num
sign = (1 if i == '+' else -1) * stack[-1]
num = 0
return ans + sign * num
기본적인 계산기를 조작하는 방법을 구현하는 문제이다. 계산기 조작 문제는 매번 할 때 마다 헷갈린다.
문제에서 주어진 연산은 덧셈, 뺄셈, 괄호이다. 공백은 어차피 처리하지 않으면 자연스레 빠지게 되니 이 부분은 잘 고려하여 구현해보자.
계산기를 사용할 때를 생각해보자. 우리는 숫자를 연속해서 누르게 되면, 숫자가 10배씩 계속 증가한다. 예를 들어, 100만을 계산기에 작성할 때는 먼저 1을 넣고, 0을 연속해서 6개를 누른다.
이 과정을 if i.isdigit() 으로 표현하였다. 만약 i가 숫자이면 저장된 num을 10의 자리로 보내고 i를 추가하는 식으로 구현하였다. 이를 손으로 써보면 잘 이해할 수 있을 것이다.
괄호에 대해서도 괄호 직전의 부호를 stack에 저장해놨다가 pop 시키는 메커니즘으로 구현해놓았다.
+, - 연산은 현재 sign * num 를 ans 에 덧셈,
현재 부호를 갱신하고
num을 0으로 초기화 한다
마지막으로 ans와 마지막 연산을 진행하면, 이 문제를 해결할 수 있다.
전형적인 계산기 문제이기 때문에, 이 구현은 실질적인 계산기를 구현하는 사이드 프로젝트에도 많이 활용되는 것으로 알고 있다. 다시 찬찬히 구현해봐야겠다.
'알고리즘 스터디' 카테고리의 다른 글
[Leetcode/파이썬]637. Average of Levels in Binary Tree (0) | 2025.03.23 |
---|---|
[Leetcode/파이썬]67. Add Binary (0) | 2025.03.16 |
[백준/파이썬][Silver II] 수열 걷기 - 4929 (0) | 2025.03.07 |
[백준/파이썬][Silver I] 데스 나이트 - 16948 (0) | 2025.03.06 |
[백준/파이썬][Bronze I] Claustrophobic Cows - 6003 (0) | 2025.03.06 |