'분류 전체보기'에 해당되는 글 230건
- 2008.06.20 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 |