중위표기법을 후위표기법으로 바꾼다음 계산 결과를 출력하는 문제입니다. 분명 이번주에 배웠는데 중위표기법을 후위표기법으로 바꾸는 부분이 잘 떠오르지 않아 구글링해가며 로직을 다시 이해했습니다. 이 문제에서는 '+', '*' 연산자만 나오기 때문에 연산자 우선순위를 간단하게 비교할수 있습니다.
먼저 중위표기법을 후위표기법으로 바꿀때, 피연산자를 만나면 후위표기법 리스트에 저장합니다. 만약 연산자가 들어온다면 이 연산자가 입력값(연산자)과 우선순위를 비교하여 우선순위가 높은 연산자를 pop해준뒤 다음 새로운 연산자를 스택에 넣어줍니다.
그 다음으로 연산자 스택에 쌓여있는 값들을 모두 후위표기법 리스트에 붙여줍니다.
마지막으로 후위표기법으로 표시된 리스트에서 연산작업을 해줍니다. 아래와 같이 동작합니다.
- 피연산자를 만나면 스택에 push
- 연산자를 만나면 필요한만큼(2개)의 피연산자를 스택에서 pop, 연산결과를 다시 스택에 push
- 수식이 끝나면 마지막으로 스택을 pop하여 출력
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Stack;
public class Solution {
static Stack<Character> midStack;
static Stack<Integer> postfixStack;
//입력값 우선순위가 더 높으면 true
//낮거나 같으면 false
public static boolean check(char input, char top) {
if(input == '*' && top != '*') return true;
else if(input == '+' && top == '*') return false;
else return false;
}
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
for (int t = 1; t <= 10; t++) {
int N = Integer.parseInt(br.readLine());
char[] mid = new char[N];
char[] result = new char[N];
midStack = new Stack<>();
mid = br.readLine().toCharArray();
int idx = 0;
//중위표기식 후위표기식으로 변환
for (int i = 0; i < N; i++) {
if(mid[i] != '+' && mid[i] != '*') { //피연산자일때
result[idx++] = mid[i];
}else {
if(midStack.empty()) {
midStack.push(mid[i]);
}else {
if(!check(mid[i], midStack.peek())) {
result[idx++] = midStack.pop();
midStack.push(mid[i]);
}else {
midStack.push(mid[i]);
}
}
}
}
while(!midStack.empty()) {
result[idx++] = midStack.pop();
}
//후위표기식 계산
postfixStack = new Stack<>();
for (int i = 0; i < result.length; i++) {
if(result[i] != '*' && result[i] != '+') {
postfixStack.push(result[i]-'0');
}else {
int r = postfixStack.pop();
int l = postfixStack.pop();
if(result[i] == '*') {
postfixStack.push(r*l);
}else {
postfixStack.push(r+l);
}
}
}
sb.append("#").append(t).append(" ").append(postfixStack.pop()).append("\n");
}
System.out.print(sb);
}
}
간단 풀이
문제에서 연산자가 '*', '+' 연산자 밖에 없고 우선순위도 곱하기 연산이 높기 때문에 먼저 곱하기 연산을 모두 해준다음 나머지 연산을 해주는 풀이를 친구에게 배웠습니다!!! 이 과정에서 곱하기 연산결과를 다시 스택에 넣고, 남은 더하기 연산을 모두 해줍니다.
공유를 허락해주신 같은반 친구!! 경섭님 감사합니다 :)
package com.java.algorithm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Stack;
public class SWEA_1223_계산기2 {
static Stack<Character> midStack;
static Stack<Integer> postfixStack;
//입력값 우선순위가 더 높으면 true
//낮거나 같으면 false
public static boolean check(char input, char top) {
if(input == '*' && top != '*') return true;
else if(input == '+' && top == '*') return false;
else return false;
}
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
for (int t = 1; t <= 10; t++) {
int N = Integer.parseInt(br.readLine());
char[] mid = new char[N];
char[] result = new char[N];
midStack = new Stack<>();
mid = br.readLine().toCharArray();
int idx = 0;
//중위표기식 후위표기식으로 변환
for (int i = 0; i < N; i++) {
if(mid[i] != '+' && mid[i] != '*') { //피연산자일때
result[idx++] = mid[i];
}else {
if(midStack.empty()) {
midStack.push(mid[i]);
}else {
if(!check(mid[i], midStack.peek())) {
result[idx++] = midStack.pop();
midStack.push(mid[i]);
}else {
midStack.push(mid[i]);
}
}
}
}
while(!midStack.empty()) {
result[idx++] = midStack.pop();
}
//후위표기식 계산
postfixStack = new Stack<>();
for (int i = 0; i < result.length; i++) {
if(result[i] != '*' && result[i] != '+') {
postfixStack.push(result[i]-'0');
}else {
int r = postfixStack.pop();
int l = postfixStack.pop();
if(result[i] == '*') {
postfixStack.push(r*l);
}else {
postfixStack.push(r+l);
}
}
}
sb.append("#").append(t).append(" ").append(postfixStack.pop()).append("\n");
}
System.out.print(sb);
}
}
'Algorithm' 카테고리의 다른 글
[SWEA] JAVA - 1210 Ladder1 (0) | 2021.02.06 |
---|---|
[SWEA] JAVA - 1873 상호의 배틀필드 (0) | 2021.02.06 |
[SWEA] JAVA - 1225 암호생성기 (1) | 2021.02.05 |
[SWEA] JAVA - 1218 괄호 짝짓기 (0) | 2021.02.05 |
[SWEA] JAVA - 5432.쇠막대기 자르기 (0) | 2021.02.05 |