#include<stdio.h>
#define MAX_EXPR_SIZE 100
#define MAX_STACK_SIZE 100
typedef enum{lparen, //0
rparen,
plus, //+
minue, //-
timee, //x
divide, ///
mod, //%
eos, //0
operand,
dsign, //$
wall, //#
and, //&
power //@
}precedence;
precedence stack[MAX_STACK_SIZE];//스텍선언
int top = 0;//스텍에 가장 위를 가르킨다.
char expr[MAX_STACK_SIZE];//입력된 수식을 저장
static int isp[] = { 0,19,12,12,13,13,13,0};//stack에 들어간 데이터에 우선순위
static int icp[] = {20,19,12,12,13,13,13,0};//stack에 들어가기 전 데이터의 우선순위
precedence get_token(char *symbol, int *n);//expr에 입력된 자료를 precedence 자료로 바꾼다
void print_token(precedence input);//스텍에 저장된 데이터를 출력한다.
precedence Delete();//스텍 Push
void add(precedence input);//스텍 pop
void postfix();//중위표기를 후위표기로 바꾸는 함수
//get_token
//expr에 입력된 자료를 precedence 자료로 바꾼다
///////////////////////////////////////////////
precedence get_token(char *symbol, int *n)
{
int i=0; // symbol[]의 인덱스로 사용될 변수
char c1; // 사용자가 입력한 수식을 한 문자씩 받아 처리하기 위한 변수
char c2; // c1변수 보다 한 단계 미리 데이타 원소를 받아 if문에서 비교에 쓰이기 위한 변수
// for(i=0; c1==operand; ++i){
// symbol[]에 피연산자 즉 한꺼번에 숫자를 저장하기 위한 무한루틴
while(1)
{
c1 = expr[(*n)++];
c2 = expr[*n]; // 다음에 체크할 문자를 미리받아 뒤의 if-조건절을 위한 변수
switch (c1) {
case '(' : return lparen;
case ')' : return rparen;
case '+' : return plus;
case '-' : return minue;
case '/' : return divide;
case '*' : return timee;
case '%' : return mod;
case '$' : return dsign;
case '#' : return wall;
case '&' : return and;
case '@' : return power;
case '\0': return eos;
default :
{
symbol[i] = c1; // symbol[]의 각 원소에 숫자를 저장
++i;
// 연산자인 경우는 리턴, 피연산자인 경우는 계속 while루프를 돈다
//'0'의 ASCII코드는 48, '9'의 코드는 57
if((c2<'0') || (c2>'9'))
{
symbol[i] = '\0'; // 문자열의 끝을 가리키는 null문자 할당
return operand;
}
}
}
}
}
///////////////////////////////////////////////
//postfix
//중위표기를 후위표기로 바꾸는 함수
///////////////////////////////////////////////
void postfix(void)
{
char symbol[6]; //1만 단위까지 가능
precedence token;
int n=0;
stack[0] = eos;
symbol[0] = '\0';
while((token = get_token(&symbol[0], &n)) != eos){
if(token == operand){
printf("%s",symbol);
}else if(token == rparen){
while(stack[top] != lparen)
print_token(Delete());
Delete();
}else{
while(isp[stack[top]] >= icp[token])
print_token(Delete());
add(token);
//if(token != lparen){
// printf(" ");
//}
}
}
while((token = Delete()) != eos){
print_token(token);
}
printf("\n");
}
///////////////////////////////////////////////
//print_token
//연산자 출력
///////////////////////////////////////////////
void print_token(precedence input)
{
switch (input) {
case plus:
printf("+");
break;
case dsign:
printf("$");
break;
case minue:
printf("-");
break;
case divide:
printf("/");
break;
case power:
printf("@");
break;
case and:
printf("&");
break;
case wall:
printf("#");
break;
case timee:
printf("*");
break;
case mod:
printf("%");
break;
default:
break;
}
return;
}
///////////////////////////////////////////////
//Delete
//스택의 pop
///////////////////////////////////////////////
precedence Delete()//pop
{
if(top < 0){//스택에 데이터가 없을때 underflow를 출력
return eos;
}
return stack[top--];
}
///////////////////////////////////////////////
//add
//스택의 push
///////////////////////////////////////////////
void add(precedence input)//push
{
if(top >= MAX_STACK_SIZE - 1){//스택이 저장용량을 넘을때 overflow를 출력
printf("\n stack overflow");
return;
}
stack[++top] = input;
return;
}
///////////////////////////////////////////////
//main
//중위표기를 후위표기로 바꾸는 함수
///////////////////////////////////////////////
void main(void){
scanf("%s", expr);
postfix();//입력된 중위표기를 후위표기로 바꾼다.
printf("end\n");
}
case가 9가지인 경우에는 긴 식을 입력해도 되는데
case 증가하니까 안댐 ㅠㅠ
즉 4+5 는 45+로 잘 되는데데
(7-2*(3+5)&9#3)*2 이런식은 입력하면 계속 입력만받음
테스트데이터가 필요타에요? - DCW
왜 이런걸 하나요?
postfix 대학2년쯤에 배우지 않나?
맞다.. 제발 알려주라 좀
http://autogram.tk/이
중고차 어플리케이션 어떤가요?