Native/C
계산기 1차
aucd29
2013. 10. 2. 18:51
/***************************************************************************
*
* Date : 2005-04-29
* Copyright : aucd29
* E-mail : aucd29@daum.net
*
* 중위 -> 후위로 그리고 과정 보여주고 계산값 보여주고
*
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
//
// definition
//
#define MAX_STACK_SIZE 100
#define MAX_EXPR_SIZE 100
#define MAX_NUM 10
typedef enum{
lparen, rparen, plus, minus, times, divide, mod, eos, operand
} precedence;
//
// variant value
//
double stack[MAX_STACK_SIZE];
double postfix_stack[MAX_EXPR_SIZE]; // 연산을 위한..
char expr[MAX_EXPR_SIZE];
double num_stack[MAX_STACK_SIZE];
static int isp[] = {0, 19, 12, 12, 13, 13, 13, 0};
static int icp[] = {20, 19, 12, 12, 13, 13, 13, 0};
int postfix_top = -1; // 후위 연산을 위해
//
// function
//
double eval(void);
int get_token(char*, int*, int);
void postfix(void);
void getline(char *);
void print_token(int);
double rmstack(int *);
void add(int*, int);
void ToStr(char* ,int*);
void push(double);
double pop(void);
void eval(double op1, double op2, int token);
int main(int argc, char *argv[])
{
//
// 중위 표기식 입력 받고
//
getline(expr);
//
// 중위식을 후위식으로 바꾸고 프린트
//
postfix();
return 0;
}
//
// 배열에 주소에 내용을 입력 받는다.
//
void getline(char *s)
{
int c, i;
for(i=0;(c=getchar()) !='\n'; ++i)
if(c!=' ' && MAX_EXPR_SIZE>i) *s++ = c;
s = '\0';
}
//
// 중위 표기를 후위표기로 변환한다.
//
void postfix(void)
{
char symbol[MAX_NUM];
int token,tokenx;
int n = 0;
int top = 0; // insert eos
stack[0] = eos;
int chk=0;
for(token = get_token(symbol, &n, 1); token != eos; token = get_token(symbol, &n, 1))
{
if(token == operand)
{
printf("%s ", symbol);
push(atof(symbol));
}
else if(token == rparen)
{
token = (int)rmstack(&top);
rmstack(&top); // rmstack rparen;
print_token(token);
eval(pop(),pop(),token);
}
else
{
//print_token(token);
//
// symbol 의 isp가 token의 icp보다 크거나 작으면 symbol을 제거하고 출력한다.
//
//printf("(t:%d)",top);
while(isp[(int)stack[top]] >= icp[token])
{
tokenx = (int)rmstack(&top); // 이것땜에 삽질 ㅡ.ㅡ;
print_token(tokenx);
eval(pop(),pop(),tokenx);
}
//printf("(add:%d)",token);
add(&top, token);
}
}
//printf("\n=======\n%lf,%lf,%lf\n",stack[top],stack[top-1],stack[top+1]);
//printf("(t:%d)",top);
while((token = (int)rmstack(&top)) != eos)
{
print_token(token);
eval(pop(),pop(),token);
}
printf("\nResult : %lf",postfix_stack[postfix_top]);
printf("\n");
}
int get_token(char* symbol, int* n, int recuv)
{
char c = expr[(*n)++];
/* if(*n-1==0 || get_token(symbol, n-1, 0) != operand)
{
*symbol++ = '-';
ToStr(symbol, n+1);
return operand;
}
else*/
switch(c)
{
case '-': return minus;
case '(': return lparen;
case ')': return rparen;
case '+': return plus;
case '/': return divide;
case '*': return times;
case '%': return mod;
case '\0': return eos;
default:
if(recuv)
{
*symbol++ = c;
ToStr(symbol, n);
}
return operand;
}
}
void ToStr(char* symbol,int* n)
{
while(get_token(symbol, n, 0) == operand)
*symbol++ = expr[*n-1];
*symbol = '\0';
--*n;
}
void print_token(int n)
{
switch(n)
{
case minus: printf("-"); break;
case lparen: printf("("); break;
case rparen: printf(")"); break;
case plus: printf("+"); break;
case divide: printf("/"); break;
case times: printf("*"); break;
case mod: printf("%");break;
}
printf(" ");
}
double rmstack(int* top)
{
return stack[(*top)--]; // 리턴후 스텍 감소
}
void add(int* top, int token)
{
stack[++*top] = token; // 증가후 토큰 입력
}
//
// overloading
//
void add(int* top, double token)
{
stack[++*top] = token; // 증가후 토큰 입력
}
void push(double f)
{
postfix_stack[++postfix_top] = f;
}
double pop(void)
{
return postfix_stack[postfix_top--];
}
void eval(double op1, double op2, int token)
{
//printf("\neval(%lf, %lf)\n", op1, op2);
switch(token)
{
case plus:
push(op1 + op2);
break;
case minus :
push(op1 - op2);
break;
case times :
push(op1 * op2);
break;
case divide:
push(op1 / op2);
break;
case mod :
push((int)op1 % (int)op2);
break;
}
/*int token;
char symbol[MAX_NUM];
double op1, op2;
int n = 0;
int top = -1;
while((token = get_token(symbol, &n, 1)) != eos)
{
if(token == operand)
add(&top, atof(symbol)); // push
else
{
op2 = rmstack(&top); // pop
op1 = rmstack(&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, (int)op1 % (int)op2);
break;
}
}
}
return rmstack(&top);*/
}
*
* Date : 2005-04-29
* Copyright : aucd29
* E-mail : aucd29@daum.net
*
* 중위 -> 후위로 그리고 과정 보여주고 계산값 보여주고
*
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
//
// definition
//
#define MAX_STACK_SIZE 100
#define MAX_EXPR_SIZE 100
#define MAX_NUM 10
typedef enum{
lparen, rparen, plus, minus, times, divide, mod, eos, operand
} precedence;
//
// variant value
//
double stack[MAX_STACK_SIZE];
double postfix_stack[MAX_EXPR_SIZE]; // 연산을 위한..
char expr[MAX_EXPR_SIZE];
double num_stack[MAX_STACK_SIZE];
static int isp[] = {0, 19, 12, 12, 13, 13, 13, 0};
static int icp[] = {20, 19, 12, 12, 13, 13, 13, 0};
int postfix_top = -1; // 후위 연산을 위해
//
// function
//
double eval(void);
int get_token(char*, int*, int);
void postfix(void);
void getline(char *);
void print_token(int);
double rmstack(int *);
void add(int*, int);
void ToStr(char* ,int*);
void push(double);
double pop(void);
void eval(double op1, double op2, int token);
int main(int argc, char *argv[])
{
//
// 중위 표기식 입력 받고
//
getline(expr);
//
// 중위식을 후위식으로 바꾸고 프린트
//
postfix();
return 0;
}
//
// 배열에 주소에 내용을 입력 받는다.
//
void getline(char *s)
{
int c, i;
for(i=0;(c=getchar()) !='\n'; ++i)
if(c!=' ' && MAX_EXPR_SIZE>i) *s++ = c;
s = '\0';
}
//
// 중위 표기를 후위표기로 변환한다.
//
void postfix(void)
{
char symbol[MAX_NUM];
int token,tokenx;
int n = 0;
int top = 0; // insert eos
stack[0] = eos;
int chk=0;
for(token = get_token(symbol, &n, 1); token != eos; token = get_token(symbol, &n, 1))
{
if(token == operand)
{
printf("%s ", symbol);
push(atof(symbol));
}
else if(token == rparen)
{
token = (int)rmstack(&top);
rmstack(&top); // rmstack rparen;
print_token(token);
eval(pop(),pop(),token);
}
else
{
//print_token(token);
//
// symbol 의 isp가 token의 icp보다 크거나 작으면 symbol을 제거하고 출력한다.
//
//printf("(t:%d)",top);
while(isp[(int)stack[top]] >= icp[token])
{
tokenx = (int)rmstack(&top); // 이것땜에 삽질 ㅡ.ㅡ;
print_token(tokenx);
eval(pop(),pop(),tokenx);
}
//printf("(add:%d)",token);
add(&top, token);
}
}
//printf("\n=======\n%lf,%lf,%lf\n",stack[top],stack[top-1],stack[top+1]);
//printf("(t:%d)",top);
while((token = (int)rmstack(&top)) != eos)
{
print_token(token);
eval(pop(),pop(),token);
}
printf("\nResult : %lf",postfix_stack[postfix_top]);
printf("\n");
}
int get_token(char* symbol, int* n, int recuv)
{
char c = expr[(*n)++];
/* if(*n-1==0 || get_token(symbol, n-1, 0) != operand)
{
*symbol++ = '-';
ToStr(symbol, n+1);
return operand;
}
else*/
switch(c)
{
case '-': return minus;
case '(': return lparen;
case ')': return rparen;
case '+': return plus;
case '/': return divide;
case '*': return times;
case '%': return mod;
case '\0': return eos;
default:
if(recuv)
{
*symbol++ = c;
ToStr(symbol, n);
}
return operand;
}
}
void ToStr(char* symbol,int* n)
{
while(get_token(symbol, n, 0) == operand)
*symbol++ = expr[*n-1];
*symbol = '\0';
--*n;
}
void print_token(int n)
{
switch(n)
{
case minus: printf("-"); break;
case lparen: printf("("); break;
case rparen: printf(")"); break;
case plus: printf("+"); break;
case divide: printf("/"); break;
case times: printf("*"); break;
case mod: printf("%");break;
}
printf(" ");
}
double rmstack(int* top)
{
return stack[(*top)--]; // 리턴후 스텍 감소
}
void add(int* top, int token)
{
stack[++*top] = token; // 증가후 토큰 입력
}
//
// overloading
//
void add(int* top, double token)
{
stack[++*top] = token; // 증가후 토큰 입력
}
void push(double f)
{
postfix_stack[++postfix_top] = f;
}
double pop(void)
{
return postfix_stack[postfix_top--];
}
void eval(double op1, double op2, int token)
{
//printf("\neval(%lf, %lf)\n", op1, op2);
switch(token)
{
case plus:
push(op1 + op2);
break;
case minus :
push(op1 - op2);
break;
case times :
push(op1 * op2);
break;
case divide:
push(op1 / op2);
break;
case mod :
push((int)op1 % (int)op2);
break;
}
/*int token;
char symbol[MAX_NUM];
double op1, op2;
int n = 0;
int top = -1;
while((token = get_token(symbol, &n, 1)) != eos)
{
if(token == operand)
add(&top, atof(symbol)); // push
else
{
op2 = rmstack(&top); // pop
op1 = rmstack(&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, (int)op1 % (int)op2);
break;
}
}
}
return rmstack(&top);*/
}