INFIX->POSTFIX

|

#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;

precedence pstack[MAX_STACK_SIZE];       
int        stack[MAX_STACK_SIZE];

char       expr[MAX_EXPR_SIZE];

static int isp[ ] = { 0, 19, 12, 12, 13, 13, 13, 0};
static int icp[ ] = {20, 19, 12, 12, 13, 13, 13, 0};


void add(int *top, int item);                    //stack에 삽입
void padd(int *top, precedence item);            //pstack에 삽입
int delete1(int *top);                            //stack에서 삭제
precedence pdelete(int *top);                    //pstack에서 삭제
precedence get_token(char *symbol, int *n);        //문자를 토큰으로
int eval(void);                                    //후위표기식 계산
char print_token(precedence token);                //토큰을 문자로
void postfix(void);                                //중위를 후위로


void main()
{
    printf("수식을 입력하시오 [중위표기] = ");
    scanf("%s",expr);

    strcat(expr," ");            //수식에 eos 연결 (공백 삽입)
    printf("[중위표기] %s\n",expr);

    postfix( );

    printf("[후위표기] %s\n",expr);
    printf("계산결과 = %d\n",eval( ));
}


void add(int *top, int item)
{
   if(*top >= MAX_STACK_SIZE-1)
   {
      fprintf(stderr,"\n스택이 꽉 찼습니다.\n");   /* print error message */
      exit(1);
   }
   stack[++*top]=item;
}

void padd(int *top, precedence item)
{
   if(*top >= MAX_STACK_SIZE-1)
   {
      fprintf(stderr,"\n스택이 꽉 찼습니다.\n");   /* print error message */
      exit(1);
   }
   pstack[++*top]=item;
}

int delete1(int *top)
{
   if(*top == -1)
   {
       fprintf(stderr,"\n스택이 비었습니다.\n");
       exit(1);
   }
   return stack[(*top)--];
}

precedence pdelete(int *top)
{
   if(*top == -1)
   {
       fprintf(stderr,"\n스택이 비었습니다.\n");
       exit(1);
   }
   return pstack[(*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 divide;
        case '*' : return times;
        case '%' : return mod;
        case ' ' : return eos;
        default  : return operand;
    }
}

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 = delete1(&top);        //스택 삭제    
            op1 = delete1(&top);        //스택 삭제
            switch(token)
            {
            case plus  : add(&top,op1+op2); break;
            case minus : add(&top,op1-op2); break;
            case times : add(&top,op1*op2); break;
            case divide: add(&top,op1/op2); break;
            case mod   : add(&top,op1%op2); break;
            }
        }
        token = get_token(&symbol, &n);
    }
    return delete1(&top);                //결과를 반환
}

char print_token(precedence token)
{
   switch (token)
   {
      case lparen : return '(';
      case rparen : return ')';
      case plus   : return '+';
      case minus  : return '-';
      case divide : return '/';
      case times  : return '*';
      case mod    : return '%';
      case eos    : return ' ';
      default     : return ' ';
  }
}


void postfix(void)
{    //수식을  후위 표기식으로 출력한다.
    precedence token;
   
    char symbol, pexpr[MAX_EXPR_SIZE];
    int pn=0,n=0, top=0;
    pstack[0]=eos;

    token = get_token(&symbol, &n);
 
    while (token != eos) 
    {
        if(token == operand)
        {
            pexpr[pn++]=symbol;
        }
        else if (token == rparen)
        {        //왼쪽 괄호가 나올때까지 토큰들을 제거해서 출력시킴
            while(pstack[top] != lparen)
                pexpr[pn++]=print_token(pdelete(&top));
            pdelete(&top);
        }
        else 
        {       
            //simbol의 isp가 token의 icp보다 크거나 같으면 symbol을 제거하고 출력시킴
            while(isp[pstack[top]] >= icp[token])
                pexpr[pn++]=print_token(pdelete(&top));
            padd(&top,token);
        }
        token = get_token(&symbol, &n);
    }
    while( (token=pdelete(&top)) != eos )
        pexpr[pn++]=print_token(token);
    pexpr[pn++]=' ';
    pexpr[pn]='\0';
    strcpy(expr,pexpr);
}




'C/C++/MFC > Source' 카테고리의 다른 글

[ Ojbect-C ] 윈도우에서 Object-c 사용하기/스크랩/  (0) 2010.02.02
Pitch Class  (0) 2008.06.20
BST-Binary Search Tree  (0) 2008.06.20
And