프로그래밍/C/C++

후위표기법을통한 계산알고리즘

Songker 2008. 10. 19. 14:47

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

#define MAX_STACK_SIZE 100
#define MAX_EXPR_SIZE 100

typedef enum{  
 plus,
 minus,
 times,
 divide,
 mod,
 cos,
 operand
}precedence;

int stack[MAX_STACK_SIZE];
char expr[MAX_EXPR_SIZE]; // 사용자로부터의 값을 저장할 메모리

void add_stack(int *top, int item)
{
 
 if(*top>=MAX_STACK_SIZE-1)
 {
  printf("Error : Stack is full.\n");
  exit(1);
 }

 ++(*top);
 stack[*top]=item;
}

int delete_stack(int *top)
{
 if(*top==-1)
 {
  printf("Error : Stack is empty.\n");
  exit(1);
 }

 return stack[(*top)--];  // 현재 top이 가리키는 값을 리턴시킨후 top의 값을 1줄인다.
}

precedence get_token(char *symbol,int *n)
{
 *symbol=expr[*n]; // 1바이트를 읽고
 (*n)++;           // 1바이트 뒤로 -> 다음글자로 포인트를 옮겨 놓는다.

 switch(*symbol)
 {
 case '+' : return plus;
 case '-' : return minus;
 case '*' : return times;
 case '/' : return divide;
 case '%' : return mod;
 case 0   :
 case '\n':
   return cos;  // 입력의 마지막을 의미

 default  : return operand;
 }
}

int eval(void)
{
 precedence token;

 char symbol;
 int op1,op2;
 int n=0;
 int top=-1;

 token=get_token(&symbol,&n);

 for( ; token!=cos ; token=get_token(&symbol,&n))
 {
  if (token==operand)
  {
   add_stack(&top,symbol-'0');  // 입력받은것을 문자로받았기때문에
  }         //  '0'의 아스키 값을 빼줌으로써숫자를 얻음
  else
  {
   op2=delete_stack(&top);
   op1=delete_stack(&top);
   
   switch(token)
   {
   case plus   : add_stack(&top,op1+op2) ; break;
   case minus  : add_stack(&top,op1-op2) ; break;
   case times  : add_stack(&top,op1*op2) ; break;
   case divide : add_stack(&top,op1/op2) ; break;
   case mod    : add_stack(&top,op1%op2) ; break;
   }
  }
 }

 return delete_stack(&top);
}

int main(void)
{
 int result;

 printf("input postfix expression : ");
 scanf("%s",expr);
 result=eval();
 printf("result : %d",result);
 return 0;
}

----------------------------

입력값 : 65*3-
계산식: 6*5-3
결과 : 27

P.S.
*n++ 과
(*n)++ 은 다르다.

연산의 우선순위에서 ++이 우선이기 때문에,
포인터의 값을 변환할때는 꼭 ( ) 를 쓰도록하자