#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_STACK_SIZE 100 //스택 크기
#define MAX_EXPR_SIZE 100 //식 크기
typedef enum { lparen, rparen, plus, minus, times, divide, mod, eos, operand } precedence;
int stack[MAX_STACK_SIZE];
char expr[MAX_EXPR_SIZE];
char exprt[MAX_EXPR_SIZE];
int eval();
void postfix();
char print_token(precedence); //precedence->우선순위
precedence get_token(char*, int*);
void add(int*, int); //추가
int delete(int*); //삭제
void stack_full(); //차있는 스택
void stack_empty(); //비어있는 스택
static int isp[] = { 0,19,12,12,13,13,13,0 };
static int icp[] = { 20,19,12,12,13,13,13,0 };
void main() {
printf("잠깐\a!!! 문제를 내라 만약 어려우면 지나가게 해주지!!!크흐흐흐 : \n");
scanf("%s", expr);
postfix(expr,exprt);
printf("expr =%s\n", expr);
printf("exprt=%s\n", exprt);
strcpy(exprt, expr);
printf("크흐흐 쉽구만 겨우 이정도 문제를 내다니 크ㅋ흐ㅋㅎㅋ흐 \n");
printf("답은 %d다. 내가 맞췄으니 넌 내 먹이다 \'냠\'!!!", eval());
}
void postfix() //후위 표기식
{
char symbol;
precedence token;
int n = 0;
int i = 0;
int top = -1;
stack[++top] = eos;
for (token = get_token(&symbol, &n); token != eos; token = get_token(&symbol, &n))
{
if (token == operand)
exprt[i++] = symbol;
else if (token == rparen)//괄호가 닫힐 때까지
{
while (stack[top] != lparen)
exprt[i++] = print_token(delete(&top));
delete(&top);
}
else
{
while (isp[stack[top]] >= icp[token])
exprt[i++] = print_token(delete(&top));
add(&top, token);
}
}
while ((token = delete(&top)) != eos)
exprt[i++] = print_token(token);
exprt[i] = '\0';
}
char print_token(precedence t)
{
switch (t)
{
case plus:
return '+';
break;
case minus:
return '-';
break;
case times:
return '*';
break;
case divide:
return '/';
break;
case mod:
return'%';
break;
}
return'\0';
}
int eval(void)
{
precedence token;
char symbol;
int op1, op2; //지워진 값 기억하는 변수
int n = 0; //문자열 수
int top = -1;
token = get_token(&symbol, &n);
while (token != eos)
{
if (token == operand)
add(&top, symbol - '0'); //슬택에 추가
else
{
op2 = delete(&top);//삭제된 스택을 저장
op1 = delete(&top);// ||(위와 같다)
switch (token)
{
case plus:
printf("%d %d + =%d\n", op1, op1, op1 + op2);
add(&top, op1 + op2);
break;
case minus:
printf("%d %d - =%d\n", op1, op1, op1 - op2);
add(&top, op1 - op2);
break;
case times:
printf("%d %d * =%d\n", op1, op1, op1 * op2);
add(&top, op1 * op2);
break;
case divide:
printf("%d %d / =%d\n", op1, op1, op1 / op2);
add(&top, op1 / op2);
break;
case mod:
printf("%d %d % =%d\n", op1, op1, op1 % op2);
add(&top, op1 % op2);
break;
}
}
token = get_token(&symbol, &n);
}
return delete(&top); //결과를 돌려줌
}
precedence get_token(char*symbol, int*n)
{
*symbol = expr[(*n)++];
switch (*symbol)
{
case'(':
return lparen;
case')':
return rparen;
case'+':
return plus;
case'-':
return minus;
case'*':
return times;
case'/':
return divide;
case'%':
return mod;
case'\0':
return eos;
default:
return operand;
}
}
void add(int *top, int item)//습택에 item추가
{
if (*top >= MAX_STACK_SIZE - 1)
{
stack_full();
return;
}
stack[++*top] = item;
}
int delete(int*top)
{
if (*top == -1)
stack_empty();
return stack[(*top)--];
}
void stack_full()
{
fprintf(stderr, "자리없다.임마 꽉 찻어\n");
exit(1);
}
void stack_empty()
{
fprintf(stderr, "아무것도 없다. 임마 비었어\n");
exit(1);
}