본문 바로가기
data structure practice

과제 3 . Postfix 계산 예제

by greentealover1 2023. 3. 19.
#include <iostream>
using namespace std;
#define MAX_STACK_SIZE 20

inline void error(char* message) {
    cout << message;
    exit(1);
}

class OperandStack {
    int top;            // 요소의 개수
    int arr[100], idx = 0;//이따가 스택 배열을 복사할 임의의 배열과 인덱스idx값 초기화
    double data[MAX_STACK_SIZE]; // 요소의 배열

public:
    OperandStack() { top = -1; }
    ~OperandStack() {}  

    bool isEmpty() { return top == -1; }
    bool isFull() { return top == MAX_STACK_SIZE - 1; }

    void push(double e) { // 맨 위에 항목 삽입
        if (isFull()) 
            error((char*)"스택 포화 에러");
        data[++top] = e;
        arr[idx++] = top + 1;  //push하고 현재 스택의 항목 수를 저장(top+1)
    }
    double pop() { //맨 위의 요소를 삭제하고 반환
        if (isEmpty()) 
            error((char*)"스택 공백 에러");
        return data[top--];
    }
    double peek() { //삭제하지 않고 요소 반환
        if (isEmpty()) 
            error((char*)"스택 공백 에러");
        return data[top];
    }
    void display() { //스택 내용을 화면에 출력
        for (int i = top; i >= 0; i--) 
            cout << data[i] << endl;
        cout << endl;
    }
    void copy(OperandStack s) { //스택 내용 복사
        top = s.top;//top요소의 개수에 OperandStack객체s의 top값을 대입
        for (int i = 0; i <= top; i++) 
            data[i] = s.data[i];//스택 내용 복사해주기
    }
    int findmax() { // 스택안에 있는 값 중 최대값 찾기
        int m = 0;
        for (int i = 0; i < idx; i++) {
            if (m < arr[i]) //스택 배열 중 가장 최댓값 찾기
                m = arr[i];
        }
        return m;
    }
    int countMax() { //스택이 가장 찬 상태의 횟수 구하기
        int count = 0;
        int m = findmax();
        for (int i = 0; i < idx; i++) {
            if (m == arr[i]) 
                count++;
        }
        return count;
    }
};
double calcPostfixExpr(FILE* fp = stdin) {
    char c;//연산자를 char형으로 본다
    double val;
    OperandStack st, rs;
    int count = 0;
    while ((c = getc(fp)) != '\n') {                         
        if (c == '+' || c == '-' || c == '*' || c == '/') {     
            count++;
            if (count == 3) 
                rs.copy(st);//rs에 st의 내용 복사
            double val2 = st.pop();         
            double val1 = st.pop();	                       
            switch (c) {
            case '+': st.push(val1 + val2); break;     
            case '-': st.push(val1 - val2); break;             
            case '*': st.push(val1 * val2); break;             
            case '/': st.push(val1 / val2); break;
            }
        }
        else if (c >= '0' && c <= '9') {                  
            ungetc(c, fp);                            
            fscanf_s(fp, "%lf", &val);    
            st.push(val);	                               
        }
    }
    cout << endl << st.findmax() << endl;//스택 항목개수가 최대일때 최댓값을 출력
    cout << st.countMax() << endl;//스택이 가득찬 상태 횟수가 몇번인지 출력
    cout << "----------------------" << endl;

    rs.display();//계산 결과 출력
    cout << "----------------------" << endl;
    return (st.pop());	  
}

int main() {
    cout << "수식 입력 = ";
    double res = calcPostfixExpr();
    cout << res << endl;    
}

후기: 프로젝트 2번 과제보다 개인적으로 어려웠다.

후위 표기 스택을 구현하고 피연산자, 연산자를 구분해서 계산시키는 것 이후부터 특정 조건 이하에서의 스택 결과를 출력하는 예제가 굉장히 어려웠다....