1935 - 후위 표기식2

김성환·2021년 11월 23일
0

코딩테스트

목록 보기
10/12

문제

https://www.acmicpc.net/problem/1935

내 풀이 분석

이번 문제는 스택을 사용하는 전형적인 문제이다. 하지만 소수를 계산해야 한다는 점과
주어진 피연산자값을 어떻게 치환할 것인가 에 대한 처리가 조금 까다로웠던 문제이다.
일단 소수를 계산하기 위해선 double형을 사용해야 했다.
그리고 답을 출력 시 소수점 2자리 까지 출력을 해야 하기 때문에 printf를 사용했다.
printf를 사용하면 변환문자(%d 등등)를 사용할 수 있다.
그리고 주어진 피연산자 값을 치환 하기위해 스택에 값을 집어 넣기 전에 A~Z까지의 수를 알맞게 집어 넣었다.
원래 나의 풀이는 주어진 후위연산표기식에 A~Z까지의 알맞는 수를 먼저 치환하였다.
예를들어 ABC+-(A=1,B=2,C=3)을 치환할 경우 123+-
하지만 AA+(A가 10일 경우)를 치환하면 1010+가 되어버려 2자리수 이상의 수를 치환하려면 다른 방법이 필요했다. 따라서 미리 식을 치환하지 않고 스택에 값을 집어 넣을때 각 알파벳 글자에 알맞는 수를 넣어주었다.

import java.util.*;
class Main {
    public static void main(String argv[]) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String str = new String(sc.next());
        int[] numbers = new int[n];
        Stack<String> st = new Stack<>();
        int stringLength = str.length();
        for(int i=0;i<n;i++){
            int num = sc.nextInt();
            numbers[i]=num;
        }
        for(int i=0;i<stringLength;i++){
            if(st.empty()){
                switch (str.charAt(i)){
                    case 'A':st.push(String.valueOf(numbers[0]));break;
                    case 'B':st.push(String.valueOf(numbers[1]));break;
                    case 'C':st.push(String.valueOf(numbers[2]));break;
                    case 'D':st.push(String.valueOf(numbers[3]));break;
                    case 'E':st.push(String.valueOf(numbers[4]));break;
                    case 'F':st.push(String.valueOf(numbers[5]));break;
                    case 'G':st.push(String.valueOf(numbers[6]));break;
                    case 'H':st.push(String.valueOf(numbers[7]));break;
                    case 'I':st.push(String.valueOf(numbers[8]));break;
                    case 'J':st.push(String.valueOf(numbers[9]));break;
                    case 'K':st.push(String.valueOf(numbers[10]));break;
                    case 'L':st.push(String.valueOf(numbers[11]));break;
                    case 'M':st.push(String.valueOf(numbers[12]));break;
                    case 'N':st.push(String.valueOf(numbers[13]));break;
                    case 'O':st.push(String.valueOf(numbers[14]));break;
                    case 'P':st.push(String.valueOf(numbers[15]));break;
                    case 'Q':st.push(String.valueOf(numbers[16]));break;
                    case 'R':st.push(String.valueOf(numbers[17]));break;
                    case 'S':st.push(String.valueOf(numbers[18]));break;
                    case 'T':st.push(String.valueOf(numbers[19]));break;
                    case 'U':st.push(String.valueOf(numbers[20]));break;
                    case 'V':st.push(String.valueOf(numbers[21]));break;
                    case 'W':st.push(String.valueOf(numbers[22]));break;
                    case 'X':st.push(String.valueOf(numbers[23]));break;
                    case 'Y':st.push(String.valueOf(numbers[24]));break;
                    case 'Z':st.push(String.valueOf(numbers[25]));break;
                }
            }
            else{
                if(str.charAt(i)=='*'||str.charAt(i)=='/'||str.charAt(i)=='+'||str.charAt(i)=='-'){
                    double n2 = Double.valueOf(st.pop());
                    double n1 = Double.valueOf(st.pop());
                    switch (str.charAt(i)){
                        case '*': st.push(String.valueOf(n1*n2));break;
                        case '/': st.push(String.valueOf(n1/n2));break;
                        case '+': st.push(String.valueOf(n1+n2));break;
                        case '-': st.push(String.valueOf(n1-n2));break;
                    }
                }
                else{
                    switch (str.charAt(i)){
                        case 'A':st.push(String.valueOf(numbers[0]));break;
                        case 'B':st.push(String.valueOf(numbers[1]));break;
                        case 'C':st.push(String.valueOf(numbers[2]));break;
                        case 'D':st.push(String.valueOf(numbers[3]));break;
                        case 'E':st.push(String.valueOf(numbers[4]));break;
                        case 'F':st.push(String.valueOf(numbers[5]));break;
                        case 'G':st.push(String.valueOf(numbers[6]));break;
                        case 'H':st.push(String.valueOf(numbers[7]));break;
                        case 'I':st.push(String.valueOf(numbers[8]));break;
                        case 'J':st.push(String.valueOf(numbers[9]));break;
                        case 'K':st.push(String.valueOf(numbers[10]));break;
                        case 'L':st.push(String.valueOf(numbers[11]));break;
                        case 'M':st.push(String.valueOf(numbers[12]));break;
                        case 'N':st.push(String.valueOf(numbers[13]));break;
                        case 'O':st.push(String.valueOf(numbers[14]));break;
                        case 'P':st.push(String.valueOf(numbers[15]));break;
                        case 'Q':st.push(String.valueOf(numbers[16]));break;
                        case 'R':st.push(String.valueOf(numbers[17]));break;
                        case 'S':st.push(String.valueOf(numbers[18]));break;
                        case 'T':st.push(String.valueOf(numbers[19]));break;
                        case 'U':st.push(String.valueOf(numbers[20]));break;
                        case 'V':st.push(String.valueOf(numbers[21]));break;
                        case 'W':st.push(String.valueOf(numbers[22]));break;
                        case 'X':st.push(String.valueOf(numbers[23]));break;
                        case 'Y':st.push(String.valueOf(numbers[24]));break;
                        case 'Z':st.push(String.valueOf(numbers[25]));break;
                    }
                }
            }
        }
        System.out.printf("%.2f",Double.valueOf(st.peek()));
    }
}

다른 사람 풀이 분석

나의 경우 스택에 알파벳에 알맞은 수를 넣을때 SWITCH문을 이용해 일일이 매칭을 해줬다.
하지만 아스키코드를 이용하면 더 짧게 코드를 작성할 수 있다.
알파벳-'A' 이면 0~25까지 수가 나오게 된다.(문제에서는 대문자 알파벳만 사용되기 때문)

import java.util.Scanner;
import java.util.Stack;
class Main
{
	public static void main(String args[]) 
	{
		Scanner sc = new Scanner(System.in);
		StringBuilder sb = new StringBuilder();
    Stack<Double> stack = new Stack<>();
    int N = Integer.parseInt(sc.nextLine());
    String input = sc.nextLine();
    double[] items = new double[N];
    for(int i = 0; i< N ; i++){
      items[i] = sc.nextInt();
    }
    for(int i = 0; i<input.length(); i++){
      char ch = input.charAt(i);
      if(ch>='A'&&ch<='Z'){
        stack.push(items[ch-'A']);
      }
      else if (ch == '*'){
        stack.push(stack.pop()*stack.pop());
      }
      else if (ch == '/'){
        double tmp = stack.pop();
        stack.push(stack.pop()/tmp);
      }
      else if (ch == '+') {
        stack.push(stack.pop()+stack.pop());
      }
      else if (ch == '-') {
        Double tmp = stack.pop();
        stack.push(stack.pop()-tmp);
      }
    }
    System.out.printf("%.2f",stack.peek());
  } 
}

결론

출력 서식을 지키기 위해서는 printf를 사용하자
스택에 값을 추가할때 어떤 방식으로 값을 추가할 것인가 생각하자

profile
개발자가 되고 싶다

0개의 댓글