Native/C
계산기
aucd29
2013. 10. 2. 18:51
// 중위 -> 후위로 그리고 과정 보여주고 계산값 보여주고
#include <stdio.h>
//
// defintion
//
#define MAX_STACK_SIZE 100
#define MAX_EXPR_SIZE 100
typedef enum{
lparen, rparen, plus, minus, times, divide, mod, eos, operand
}precedence;
//
// variant value
//
int stack[MAX_STACK_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};
//
// function
//
/*int eval(void);*/
precedence get_token(char*, int*);
void postfix(void);
void getline(char *);
void print_token(precedence);
precedence remove(int *):
void add(int*, precedence);
int main(int argc, char *argv[])
{
//
// 중위 표기식 입력 받고
//
getline(expr);
//
// 중위식을 후위식으로 바꾸고
//
postifx();
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 postifx(void)
{
char symbol[100];
char *FirstSymbol = symbol;
precedence token;
int n = 0;
int top = 0; // insert eos
int num_top = 0;
stack[0] = eos;
for(token = get_token(symbol, &n); token != eos; token = get_token(symbol, &n))
{
if(token == operand)
{
*symbol = '\0';
printf("%s", symbol);
//num_stack[num_top++] = atof(symbol);
}
else if(token == rparen)
{
print_token(remove(&top));
remove(&top); // remove rparen;
}
else
{
// symbol 의 isp가 token의 icp보다 크거나 작으면 symbol을 제거하고 출력한다.
while(isp[stack[top]] >= icp[token])
print_token(remove(&top));
add(&top, token);
}
symbol = FirstSymbol; // init
}
while((token = remove(&top)) != eos)
print_token(token);
printf("\n");
}
precedence get_token(char* symbol, int* n)
{
char c;
switch(c = expr[(*n)++])
{
case '-':
// if(n-1==0 || get_token(expr[*n-2], n) != openrand)
// {
// *symbol++ = '-';
// return get_token(symbol, n);
// }
// else
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:
*symbol++ = c;
while(get_token(symbol, n)==openrand);
//*symbol++ = c;
return openrand;
}
}
void print_token(precedence 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;
case eos: printf("\0");break;
}
}
precedence remove(int* top)
{
--*top;
return stack[*top];
}
void add(int* top, precedence token)
{
stack[++*top] = token;
}
/*
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'); // insert stack
else
op2 = remove(&top); // delete stack
op1 = remove(&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 remove(&top); // return result
}
*/
#include <stdio.h>
//
// defintion
//
#define MAX_STACK_SIZE 100
#define MAX_EXPR_SIZE 100
typedef enum{
lparen, rparen, plus, minus, times, divide, mod, eos, operand
}precedence;
//
// variant value
//
int stack[MAX_STACK_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};
//
// function
//
/*int eval(void);*/
precedence get_token(char*, int*);
void postfix(void);
void getline(char *);
void print_token(precedence);
precedence remove(int *):
void add(int*, precedence);
int main(int argc, char *argv[])
{
//
// 중위 표기식 입력 받고
//
getline(expr);
//
// 중위식을 후위식으로 바꾸고
//
postifx();
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 postifx(void)
{
char symbol[100];
char *FirstSymbol = symbol;
precedence token;
int n = 0;
int top = 0; // insert eos
int num_top = 0;
stack[0] = eos;
for(token = get_token(symbol, &n); token != eos; token = get_token(symbol, &n))
{
if(token == operand)
{
*symbol = '\0';
printf("%s", symbol);
//num_stack[num_top++] = atof(symbol);
}
else if(token == rparen)
{
print_token(remove(&top));
remove(&top); // remove rparen;
}
else
{
// symbol 의 isp가 token의 icp보다 크거나 작으면 symbol을 제거하고 출력한다.
while(isp[stack[top]] >= icp[token])
print_token(remove(&top));
add(&top, token);
}
symbol = FirstSymbol; // init
}
while((token = remove(&top)) != eos)
print_token(token);
printf("\n");
}
precedence get_token(char* symbol, int* n)
{
char c;
switch(c = expr[(*n)++])
{
case '-':
// if(n-1==0 || get_token(expr[*n-2], n) != openrand)
// {
// *symbol++ = '-';
// return get_token(symbol, n);
// }
// else
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:
*symbol++ = c;
while(get_token(symbol, n)==openrand);
//*symbol++ = c;
return openrand;
}
}
void print_token(precedence 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;
case eos: printf("\0");break;
}
}
precedence remove(int* top)
{
--*top;
return stack[*top];
}
void add(int* top, precedence token)
{
stack[++*top] = token;
}
/*
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'); // insert stack
else
op2 = remove(&top); // delete stack
op1 = remove(&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 remove(&top); // return result
}
*/