|
참 어려워요..학교에서 하는거거덩요..
레포트를쓰라는데 몬소린지..ㅡㅡ;
그래서 여기에서 부탁드립니다..
고수분들은 그냥 풀거 같은데 말이죠...
문제는 post eval program 작성입니다.
input이 string으로 구성되어잇고,
이때 숫자가 한자리수 이상 다섯자리 이하라고 생각
단, 숫자와 숫자사이는 빈칸으로 분리되어 있다.
postfix eval program을 수정해서 동작할 수 있도록
input은 postfix로...
eval 프로그램....(근데 이프로그램은 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);
}
|