=중위 표기식 -> 후위 표기식 -> 연산 =
채진석교수님 강의 - 자료구조 2학년 1학기 코딩과제
#include <stdio.h>
#include <string.h>

#define MAX_STATCK_SIZE 100             // 스택의 최대 크기 
#define MAX_EXP_SIZE 100                // 수식의 최대 크기 

typedef enum { lparen, rparen, plus, minus, multiply, divide, eos, operand } precedence;

int stack_eval[MAX_STATCK_SIZE];
precedence stack_postfix[MAX_STATCK_SIZE];
char exp[MAX_EXP_SIZE];

// lparen, rparen, plus, minus, multiply, divide, eos의 우선순위 값
static int PIS[] = { 0, 3, 1, 1, 2, 2, 0 };
static int PIE[] = { 4, 3, 1, 1, 2, 2, 0 };

void push_eval(int*, int);
int pop_eval(int*);
void push_postfix(int*, precedence);
precedence pop_postfix(int*);
int evalPostfix(void);
precedence getToken(char*, int*);
void postfix(void);
char makeToken(precedence);

int evalPostfix(void)
{
	precedence token;
	char symbol;
	int op1, op2; //피연산자 두개를 받는다.
	int n = 0;
	int top = -1;
	token = getToken(&symbol, &n);
	// printf("token = %d, symbol= %c\n",token, symbol);
	while(token != eos){
		if(token == operand) push_eval(&top, symbol-'0');
		else{
			op2 = pop_eval(&top);
			op1 = pop_eval(&top);
			switch(token) {
				case plus : push_eval(&top, op1 + op2); break;
				case minus : push_eval(&top, op1 - op2); break;
				case multiply : push_eval(&top, op1 * op2); break;
				case divide : push_eval(&top, op1 / op2); break;
			}
		}
		token = getToken(&symbol, &n);
	}
	return pop_eval(&top);
}

void postfix(void)
{
	char symbol; 
	int i=0; // exp배열 인덱스
	int j, k;
	int n=0; 
	int top = -1; 
	int array[MAX_EXP_SIZE];
	precedence token; 
	token = getToken(&symbol, &n);
	while( token != eos ){ 
		switch ( token ) {
		case operand :
			exp[i++] = symbol; 
			break;
		case rparen :
			while( stack_postfix[top] != lparen ) exp[i++] = makeToken(pop_postfix(&top));
			token = pop_postfix(&top);	// 필요없어진 lparen을 버리기 위해 사용
			break;
		default :
			while( PIE[token] <= PIS[stack_postfix[top]] ) exp[i++] = makeToken(pop_postfix(&top));
			push_postfix(&top, token);          
			break;
		}
		token = getToken(&symbol, &n); 
	}
	while( top > -1 ) exp[i++] = makeToken(pop_postfix(&top)); 
	exp[i]=NULL; 
}

void push_eval(int *top, int item)
{
        if (*top >= MAX_STATCK_SIZE-1) {
                printf("Stack is full.\n");
                return;
        }
        stack_eval[++*top] = item;
}

int pop_eval(int *top)
{
        if (*top < 0) {
                printf("Stack is empty.\n");
                return -1;
        }
        return stack_eval[(*top)--];
}

void push_postfix(int *top, precedence item)
{
        if (*top >= MAX_STATCK_SIZE-1) {
                printf("Stack is full.\n");
                return;
        }
        stack_postfix[++*top] = item;
}

precedence pop_postfix(int *top)
{
        if (*top < 0) {
                printf("Stack is empty.\n");
                return eos;
        }
        return stack_postfix[(*top)--];
}

precedence getToken(char *symbol, int *n)
{
        *symbol = exp[(*n)++];
        switch (*symbol) {
                case '(' : return lparen;
                case ')' : return rparen;
                case '+' : return plus;
                case '-' : return minus;
                case '*' : return multiply;
                case '/' : return divide;
                case '\0' : return eos;
                default : return operand;
        }
}

char makeToken(precedence token)
{
        switch (token) {
                case plus : return '+';
                case minus : return '-';
                case multiply : return '*';
                case divide : return '/';
                default : return ' ';
        }
}

int main()
{		        
        int result;
        printf("중위 표기식 입력 (종료시는 xxx) : ");
        scanf("%s", exp);
        while (strcmp(exp, "xxx")) {
                postfix();
                printf("\n변환된 후위 표기식 : %s\n", exp);
                result = evalPostfix();
                printf("\n계산 결과 : %d\n", result);
                printf("\n중위 표기식 입력 (종료시는 xxx) : ");
                scanf("%s", exp);
        }
        return 0;
}
Posted by croute

댓글을 달아 주세요