본문 바로가기
study/자료구조

[스택 코드]

by 메이02 2023. 4. 15.

//알파벳 

// Alphabet

#include <iostream>
using namespace std;

#define MAX_STACK_SIZE 20

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

class OperandStack
{
    int top;
    int maxArr[100], idx = 0;
    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*)"stack overflow !");
        data[++top] = e;
        maxArr[idx++] = top + 1;  // push할 때마다 현재의 항목수 저장, top은 0부터 시작이므로 +1
    }
    double pop() {
        if (isEmpty()) error((char*)"stack empty !");
        return data[top--];
    }
    double peek() {
        if (isEmpty()) error((char*)"stack empty !");
        return data[top];
    }
    void display() {
        for (int i = top; i >= 0; i--) cout << data[i] << endl;
        cout << endl;
    }
    bool isItem(int item) {
        bool flag = false;
        for (int i = 0; i <= top; i++) 
            if (data[i] == item) {
                flag = true; 
                break;
            }
        return flag;
    }

};

int main()
{
    int n = 0;
    char ch, max;       // ch: 입력 데이터 
    OperandStack s;     // stack
    char pm[100];       // plus, minus 저장 배열
    int index = 0;      // pm[100] 배열 인덱스

    cin >> n;
    max = 'a'-1;    // max: 현재까지 스택에 들어온 알파벳 중 가장 큰 알파벳

    for (int i = 0; i < n; i++) {
        cin >> ch; 

        for (char c = max+1; c < ch; c++) { // max부터 현재 입력 데이터 바로 이전 알파벳까지 push
            s.push(c);
            pm[index++] = '+';              // 추후 출력을 위해 '+'를 배열에 저장
        }
        if (s.isEmpty() || ch != s.peek()) {   // 현재 입력 데이터가 스택 top 데이터와 다른 경우 push
            if (s.isItem(ch)) {                 // 현재 입력 데이터가 이미 스택에 pop할 수 없는 위치에 있으면 NO 출력
                cout << endl << "NO" << endl; 
                exit(1);
            }
            s.push(ch);
            pm[index++] = '+';              // 추후 출력을 위해 '+'를 배열에 저장
        }
        s.pop();                            // 현재 입력 데이터 출력
        pm[index++] = '-';                  // 추후 출력을 위해 '-'를 배열에 저장

        if (max < ch) max = ch;             // 현재까지 스택에 들어온 가장 큰 알파벳 업데이트
    }
    cout << endl;
    for (int i = 0; i < index; i++) cout << pm[i] << endl;

    return 0;
}

//postfix

// Postfix

#include <iostream>
using namespace std;

#define MAX_STACK_SIZE 20

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

class OperandStack
{
    int top;
    int maxArr[100], idx = 0;
    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*)"stack overflow !");
        data[++top] = e;
        maxArr[idx++] = top+1;  // push할 때마다 현재의 항목수 저장, top은 0부터 시작이므로 +1
    }
    double pop() {
        if (isEmpty()) error((char*)"stack empty !");
        return data[top--];
    }
    double peek() {
        if (isEmpty()) error((char*)"stack empty !");
        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;
        for (int i = 0; i <= top; i++) data[i] = s.data[i];
    }
    int getMax() {          // 항목수 중에 Max값 찾아서 출력
        int m = 0;
        for (int i = 0; i < idx; i++) {
            if (m < maxArr[i]) m = maxArr[i];
        }
        return m;
    }
    int countMax() {        // Max Count 세어서 출력
        int count = 0;
        int m = getMax();
        for (int i = 0; i < idx; i++) {
            if (m == maxArr[i]) count++;
        }
        return count;
    }
};

double calcPostfixExpr(FILE* fp = stdin) {
    char c;
    double val;
    OperandStack st, pt;
    int count = 0;

    while ((c = getc(fp)) != '\n') {                            // 파일에서 expr 한 문자 씩 읽어서
        if (c == '+' || c == '-' || c == '*' || c == '/') {     //연산자이면 
            count++;
            if (count == 3) pt.copy(st);
            double val2 = st.pop();                             //피연산자 2개 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') {                        // 피연산자이면 스택에 push
            ungetc(c, fp);                                      // 읽어 들인 문자 한 개를 반납
            fscanf_s(fp, "%lf", &val);                          // 피연산자를 실수로 read
            st.push(val);	                                    // 피연산자를 스택에 push
        }
    }
    cout << endl << st.getMax() << endl;
    cout << st.countMax() << endl;
    cout << "______________________" << endl;

    pt.display();
    cout << "______________________" << endl;

    return (st.pop());	                                        // 스택에 최종 남아있는 값은 전체 계산결과
}

int main()
{
    cout << "수식입력(postfix) = ";
    double res = calcPostfixExpr();
    cout << res << endl;        // 계산 결과 출력
    return 0;
}

'study > 자료구조' 카테고리의 다른 글

[포인터 코드]  (0) 2023.04.15
[큐 코드]  (0) 2023.04.15
[클래스 코드]  (0) 2023.04.15
[Chap5] 연결 리스트 과제  (0) 2023.04.06
[Chap5] 포인터와 연결리스트  (0) 2023.04.05