이것저것

BOJ - 1935. 후위표기식2 본문

Problem Solving

BOJ - 1935. 후위표기식2

nays111 2021. 1. 10. 20:38

문제

후위 표기식과 각 피연산자에 대응하는 값들이 주어져 있을 때, 그 식을 계산하는 프로그램을 작성하시오.

입력

첫째 줄에 피연산자의 개수(1 ≤ N ≤ 26) 가 주어진다. 그리고 둘째 줄에는 후위 표기식이 주어진다. (여기서 피연산자는 A~Z의 영대문자이며, A부터 순서대로 N개의 영대문자만이 사용되며, 길이는 100을 넘지 않는다) 그리고 셋째 줄부터 N+2번째 줄까지는 각 피연산자에 대응하는 값이 주어진다. (3번째 줄에는 A에 해당하는 값, 4번째 줄에는 B에 해당하는값 , 5번째 줄에는 C ...이 주어진다, 그리고 피연산자에 대응 하는 값은 정수이다)

출력

계산 결과를 소숫점 둘째 자리까지 출력한다.

예제 입력 1

5 ABC*+DE/- 1 2 3 4 5

예제 출력 1

6.20

예제 입력 2

1 AA+A+ 1

예제 출력 2

3.00


사용할 자료구조

  1. 피연산자를 담을 공간을 스택으로 구현하였습니다.

  2. 피연산자는 A-Z의 대문자인데 입력한 숫자에 대응해야하기 때문에 key값을 알파벳, value값을 숫자로 갖는 을 생각했습니다.

풀이 과정

1. 문제에서 A부터 순서대로 N개의 영대문자만들 사용한다고 하여 map의 key값을 A,B,C,... 순으로 하나씩 늘리며 입력받은 value값과 함께 저장해두었습니다.

 

char key='A'; for(int i=0;i<n;i++){ int value; cin>>value; mp.insert(make_pair(key,value)); key++; }

 

2. 입력받은 문자의 크기만큼 루프를 돌며 스택에 저장하였습니다.

 

2-1) 입력받은 문자가 A~Z사이의 문자일 경우(피연산자일 경우), map의 key값에 대응하는 value값을 스택에 담았습니다.

 

2-2) 연산자일 경우, 스택의 가장 위쪽에 위치한 두개의 숫자를 pop하여 계산한 이후, 다시 스택에 push 하였습니다. (다음 연산에 사용해야하므로)

 

double top1 = st.top(); st.pop(); double top2 = st.top(); st.pop(); if(str[i]=='+'){ st.push(top2+top1); }else if(str[i]=='-'){ st.push(top2-top1); }else if(str[i]=='*'){ st.push(top2*top1); }else if(str[i]=='/'){ st.push(top2/top1); }

 

 

3. 루프를 다 돌고나면 최종 결과만 스택에 남으므로 해당 결과를 출력해주면 됩니다. 문제에서 소수점 두자리까지만 출력하라고 되어있으므로, 미리 double 형태로 받았고 두자리 형식에 맞게 출력해주었습니다.

 

answer = st.top(); cout<<fixed; cout.precision(2); cout<<answer;

시간복잡도

map 에 삽입하고 탐색하는데 O(logN)만큼 걸립니다

스택에 삽입하고 삭제하는데 O(1) 만큼 걸립니다

n만큼 루프를 돌며 map에 접근하고 str.size()만큼 루프를 돌며 스택에 삽입,삭제하므로 O(nlogN)+ O(n) ⇒ O(nlogN) 입니다(?)

 

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <stack>
#include <queue>
#include <map>
#include <functional>
using namespace std;

int main(){
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(false);
    int n;
    string str;
    double answer = 0;
    stack<double> st;
    map<char,double> mp;
    cin>>n>>str;
    char key='A';
    for(int i=0;i<n;i++){
        int value;
        cin>>value;
        mp.insert(make_pair(key,value));
        key++;
    }

    for(int i=0;i<str.size();i++){
        if(str[i]-'\0'>=65 && str[i]-'\0'<=90){
            st.push(mp[str[i]]);
        }else{
            double top1 = st.top();
            st.pop();
            double top2 = st.top();
            st.pop();
            if(str[i]=='+'){ 
                st.push(top2+top1);
            }else if(str[i]=='-'){
                st.push(top2-top1);
            }else if(str[i]=='*'){
                st.push(top2*top1);
            }else if(str[i]=='/'){
                st.push(top2/top1);
            }
        }
    }
    answer = st.top();
    cout<<fixed;
    cout.precision(2);
    cout<<answer;

    return 0;
}

 

'Problem Solving' 카테고리의 다른 글

BOJ - 2841. 외계인의 기타 연주  (0) 2021.01.11
BOJ - 1715. 카드 정렬하기  (0) 2021.01.10
BOJ - 1406. 에디터  (0) 2021.01.10
BOJ - 2346. 풍선 터뜨리기  (0) 2021.01.10
BOJ - 1158. 요세푸스 문제  (0) 2021.01.10
Comments