1. 소스코드

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 스택 구조체 정의
typedef struct Stack {
    int data;
    struct Stack* next;
} Stack;

// 스택 초기화 함수
void initialize(Stack** top) {
    *top = NULL;
}

// 스택이 비어있는지 확인하는 함수
int is_empty(Stack* top) {
    return top == NULL;
}

// 스택에 원소 추가 함수
void push(Stack** top, int data) {
    Stack* newNode = (Stack*)malloc(sizeof(Stack));
    newNode->data = data;
    newNode->next = *top;
    *top = newNode;
}

// 스택에서 원소 제거 함수
void pop(Stack** top) {
    if (is_empty(*top)) {
        //printf("스택이 비어있습니다.\\n");
        return;
    }
    Stack* temp = *top;
    *top = (*top)->next;
    free(temp);
}

// 스택에서 가장 위의 원소 반환 함수
int peek(Stack* top) {
    if (is_empty(top)) {
        //printf("스택이 비어있습니다.\\n");
        return 0; // 임의의 값 반환
    }
    return top->data;
}

// 연산자의 우선순위를 반환하는 함수
int precedence(char op) {
    if (op == '+' || op == '-') {
        return 1;
    } else if (op == '*' || op == '/') {
        return 2;
    }
    return 0; // 연산자가 아닌 경우
}
// 중위 표현식을 후위 표현식으로 변환하는 함수
char* infixToPostfix(char* expression) {
    Stack* stack;
    initialize(&stack);

    int length = strlen(expression);
    char* postfix = (char*)malloc((length + 1) * sizeof(char));
    int index = 0;

    for (int i = 0; i < length; i++) {
        char token = expression[i];
        if ((token >= '0' && token <= '9') || (token >= 'a' && token <= 'z') || (token >= 'A' && token <= 'Z')) {
            // 피연산자인 경우
            postfix[index++] = token;
        } else if (token == '(') {
            // 왼쪽 괄호인 경우
            push(&stack, token);
        } else if (token == ')') {
            // 오른쪽 괄호인 경우
            while (!is_empty(stack) && peek(stack) != '(') {
                postfix[index++] = peek(stack);
                pop(&stack);
            }
            if (!is_empty(stack) && peek(stack) == '(') {
                pop(&stack); // 왼쪽 괄호 제거
            } else {
                printf("괄호 짝이 맞지 않습니다.\\n");
                free(postfix);
                return NULL;
            }
        } else {
            // 연산자인 경우
            while (!is_empty(stack) && precedence(peek(stack)) >= precedence(token)) {
                postfix[index++] = peek(stack);
                pop(&stack);
            }
            push(&stack, token);
        }
    }

    // 남아있는 연산자들을 후위 표현식에 추가
    while (!is_empty(stack)) {
        if (peek(stack) == '(') {
            printf("괄호 짝이 맞지 않습니다.\\n");
            free(postfix);
            return NULL;
        }
        postfix[index++] = peek(stack);
        pop(&stack);
    }

    postfix[index] = '\\0'; // 문자열 끝에 NULL 문자 추가
    return postfix;
}

// 후위 표현식을 계산하는 함수
int evaluate(char* postfix) {
    Stack* stack;
    initialize(&stack);

    int length = strlen(postfix);

    for (int i = 0; i < length; i++) {
        char token = postfix[i];
        if (token >= '0' && token <= '9') {
            // 피연산자인 경우
            push(&stack, token - '0'); // 문자를 숫자로 변환하여 스택에 push
        } else {
            // 연산자인 경우
            int operand2 = peek(stack);
            pop(&stack);
            int operand1 = peek(stack);
            pop(&stack);

            // 연산 수행 후 결과를 스택에 push
            switch (token) {
                case '+':
                    push(&stack, operand1 + operand2);
                    break;
                case '-':
                    push(&stack, operand1 - operand2);
                    break;
                case '*':
                    push(&stack, operand1 * operand2);
                    break;
                case '/':
                    if (operand2 == 0) {
                        printf("0으로 나눌 수 없습니다.\\n");
                        return 0;
                    }
                    push(&stack, operand1 / operand2);
                    break;
                default:
                    printf("올바르지 않은 연산자입니다.\\n");
                    return 0;
            }
        }
    }

    // 최종 결과 반환
    return peek(stack);
}

// 괄호 사용이 정상인지 체크하는 함수
void bracketCheck(char* expression) {
    Stack* stack;
    initialize(&stack);

    int length = strlen(expression);

    for (int i = 0; i < length; i++) {
        char token = expression[i];
        if (token == '(') {
            push(&stack, '(');
        } else if (token == ')') {
            if (is_empty(stack) || peek(stack) != '(') {
                printf("열린 괄호와 닫힌 괄호의 짝이 맞지 않습니다.\\n");
                return;
            }
            pop(&stack);
        }
    }

    if (!is_empty(stack)) {
        printf("열린 괄호와 닫힌 괄호의 짝이 맞지 않습니다.\\n");
    } else {
        printf("괄호 사용이 정상적입니다.\\n");
    }
}

int main() {
    char expression[100];
    
    printf("수식을 입력하세요: ");
    fgets(expression, sizeof(expression), stdin);
    
    printf("입력한 수식: %s", expression);

    // 괄호 체크
    bracketCheck(expression);

    // 중위 표현식을 후위 표현식으로 변환
    char* postfix = infixToPostfix(expression);
    if(postfix != NULL) {
        printf("후위 표현식: %s\\n", postfix);
        
        // 후위 표현식을 계산
        int result = evaluate(postfix);
        printf("계산 결과: %d\\n", result);
        
        free(postfix);
    }

    return 0;
}

2. 실행결과

Untitled

3. 고찰

후위 표현식까지는 어떻게 잘 했지만, 계산 결과에서 계속 0으로 출력되었습니다. 디버깅을 계속 해보기도 하고, ChatGPT의 힘을 빌려보려고도 했지만, 어느 지점에서 발생한 문제인지 잘 캐치가 안되어서 결국 결과값까지는 뽑아내지 못했습니다. 어려운 문제같진 않은데, 못 풀고 있으니, 마음이 참 답답한 것 같습니다