https://www.acmicpc.net/problem/1918
from collections import deque
exp = list(input())
ans = []
stack = deque()
# 연산자 우선순위를 저장하는 딕셔너리
precedence = {'+': 1, '-': 1, '*': 2, '/': 2}
for c in exp:
if c.isalpha():
ans.append(c)
elif c == '(':
stack.append(c)
elif c == ')':
while stack and stack[-1] != '(':
ans.append(stack.pop())
stack.pop() # '('를 제거
else:
# 현재 연산자와 스택 상단의 연산자 우선순위를 비교하여 처리
while stack and stack[-1] != '(' and precedence.get(stack[-1], 0) >= precedence[c]:
ans.append(stack.pop())
stack.append(c)
while stack:
ans.append(stack.pop())
answer = "".join(ans)
print(answer)
import java.io.*;
import java.util.*;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String exp = br.readLine();
System.out.println(infixToPostfix(exp));
}
private static String infixToPostfix(String exp) {
StringBuilder ans = new StringBuilder(exp.length());
Deque<Character> stack = new ArrayDeque<>();
for (int i = 0; i < exp.length(); i++) {
char c = exp.charAt(i);
if (Character.isLetter(c)) {
ans.append(c);
} else if (c == '(') {
stack.addLast(c);
} else if (c == ')') {
while (!stack.isEmpty() && stack.getLast() != '(') {
ans.append(stack.removeLast());
}
stack.removeLast(); // Remove '('
} else {
while (!stack.isEmpty() && precedence(stack.getLast()) >= precedence(c)) {
ans.append(stack.removeLast());
}
stack.addLast(c);
}
}
while (!stack.isEmpty()) {
ans.append(stack.removeLast());
}
return ans.toString();
}
private static int precedence(char op) {
switch (op) {
case '+': case '-':
return 1;
case '*': case '/':
return 2;
default:
return -1; // For '(' and any other invalid character
}
}
}
후위표기식(Postfix Notation) 계산은 스택을 활용하여 효율적으로 수행할 수 있습니다. 이번 글에서는 스택을 사용하여 연산자와 괄호를 처리하는 방식을 정리해보겠습니다.
후위표기식을 계산할 때, 스택은 연산자와 괄호를 관리하는 중요한 역할을 합니다. 스택을 통해 연산자의 우선순위를 유지하고, 괄호의 쌍을 맞추는 과정을 간편하게 처리할 수 있습니다.
스택을 이용한 후위표기식 계산은 연산자의 우선순위와 괄호 처리를 통해 정확하고 효율적인 계산을 가능하게 합니다. 이러한 방법은 자료구조의 기초를 이해하는 데 큰 도움이 되며, 다양한 알고리즘 문제에서도 유용하게 활용될 수 있습니다.
입력 부분에서 System.in
으로 스트림을 받아 문자열 처리를 위해 Reader
로 변환한 후, 이를 효율적으로 처리하기 위해 BufferedReader
를 사용하는 것이 좋습니다. BufferedReader
는 내부 버퍼를 사용하여 한 번에 여러 데이터를 읽기 때문에, Scanner
보다 훨씬 빠른 성능을 제공합니다. 특히 대량의 데이터를 다룰 때 그 차이는 더욱 두드러집니다.
StringBuilder
의 길이를 미리 알고 있다면, 해당 길이를 지정해 주어 메모리를 할당하는 것이 메모리 효율상 좋습니다. 이렇게 하면 불필요한 메모리 재할당을 줄일 수 있어 성능이 개선되고, 메모리 사용량도 최적화할 수 있습니다.
LinkedList
대신 ArrayDeque
를 사용하는 것이 좋습니다. ArrayDeque
는 배열 방식을 사용하여 메모리 접근이 연속적이기 때문에 CPU 캐시 효율성이 높아 성능이 향상됩니다. 반면, LinkedList
는 노드가 메모리 상에 분산되어 있어 비연속적 접근을 유발하고, 이로 인해 캐시 미스를 발생시켜 성능을 저하시킵니다. 또한, LinkedList
는 포인터를 저장해야 하므로 메모리 사용량도 더 높습니다.
이렇게 Python과 Java로 백준의 "후위 표기식" 문제를 해결해보았습니다. 코드와 개념 설명을 참고하여 문제를 해결하는 데 도움이 되셨길 바랍니다! 😊