스택 계산기 알고리즘(실수 계산)

2014. 11. 21. 20:49Engineering

반응형

학교에서 수행평가로 작성한 프로그램입니다~~

스택을 이용한 실수 사칙연산 계산기인데, 십진수를 이진수로, 이진수를 십진수로 변환하는 기능도 추가했습니다!!

 

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

typedef double myData;

typedef struct Node{

myData data;

struct Node *next;

}NODE;

typedef struct Stack{

NODE *head;

}myStack;

void init(myStack *ps)

{

ps->head=NULL;

}

int isEmpty(myStack *ps)

{

if(ps->head==NULL) return 1;

else return 0;

}

double binary(myData x)

{

double i=1, r, y=0;

int s;

while(i<=x){

i=i*2;

}

i=i/2;

while(x>=1){

s=0;

if(x>=i){

x=x-i;

s=1;

}

y=y*10+s;

i=i/2;

}

i=0.5;

r=0.1;

while(x>0){

s=0;

if(x>=i){

x=x-i;

s=1;

}

y=y+s*r;

r=r/10;

i=i/2;

}

return y;

}

double decimal(myData x)

{

double i=1, r, y=0, cnt=0;

int s;

while(i<=x){

i=i*10;

++cnt;

}

i=i/10;

while(x>=1){

s=0;

if(x>=i){

x=x-i;

s=1;

}

y=y*2+s;

i=i/10;

}

i=0.1;

r=0.5;

while(x>0){

s=0;

if(x>=i){

x=x-i;

s=1;

}

y=y+s*r;

r=r/2;

i=i/10;

}

return y;

}

void push(myStack *ps, myData data)

{

NODE *anode=(NODE*)malloc(sizeof(NODE));

anode->data=data;

anode->next=ps->head;

ps->head=anode;

}

myData pop(myStack *ps)

{

NODE *anode;

myData data;

if(isEmpty(ps)==1) printf("Stack is empty!\n");

else{

data=ps->head->data;

anode=ps->head;

ps->head=ps->head->next;

free(anode);

return data;

}

}

myData getTop(myStack *ps)

{

if(isEmpty(ps)==1) return 0;

else return ps->head->data;

}

int priority(int oprt)

{

switch(oprt){

case '(' :

return 0;

case '+' : case '-' :

return 1;

case '*' : case '/' :

return 2;

case 'r' :

return 3;

case 'b' :

return 4;

case 'd' :

return 5;

default :

return 6;

}

}

int isOperator(int c)

{

if(c=='+'||c=='-'||c=='*'||c=='/'||c=='r'||c=='b'||c=='d') return 1;

else return 0;

}

void toPostfix(myStack *ps, char ex1[], char ex2[])

{

int i=0, k=0;

init(ps);

while(ex1[i]!='\0'){

if(ex1[i]=='('){

push(ps,ex1[i]);

i++;

}

else if(ex1[i]==')'){

while(getTop(ps)!='('){

ex2[k++]=pop(ps);

ex2[k++]=' ';

}

pop(ps);

i++;

}

else if(isOperator(ex1[i])){

while(!isEmpty(ps)){

if(priority(getTop(ps))>=priority(ex1[i])){

ex2[k++]=pop(ps);

ex2[k++]=' ';

continue;

}

else break;

}

push(ps,ex1[i]);

i++;

}

else if(ex1[i]>='0' && ex1[i]<='9'){

do{

ex2[k++]=ex1[i++];

}while(ex1[i]>='0' && ex1[i]<='9');

ex2[k++]=' ';

}

else if(ex1[i]=='.'){

k--;

ex2[k++]='.';

i++;

}

else i++;

}

while(!isEmpty(ps)){

ex2[k++]=pop(ps);

ex2[k++]=' ';

}

ex2[--k]='\0';

}

double calc(myStack *ps, char ex1[])

{

int i=0;

double r, s;

init(ps);

while(ex1[i]!='\0'){

if(ex1[i]>='0' && ex1[i]<='9'){

r=0;

do{

r=r*10+ex1[i]-'0';

i++;

}while(ex1[i]>='0' && ex1[i]<='9');

s=1;

if(ex1[i]=='.'){

i++;

do{

s*=0.1;

r=r+(ex1[i]-'0')*s;

i++;

}while(ex1[i]>='0' && ex1[i]<='9');

}

push(ps,r);

i++;

}

else if(ex1[i]=='+'){

push(ps,pop(ps)+pop(ps));

i++;

}

else if(ex1[i]=='-'){

r=pop(ps);

push(ps,pop(ps)-r);

i++;

}

else if(ex1[i]=='*'){

push(ps,pop(ps)*pop(ps));

i++;

}

else if(ex1[i]=='/'){

r=pop(ps);

push(ps,pop(ps)/r);

i++;

}

else if(ex1[i]=='r'){

push(ps,sqrt(pop(ps)));

i++;

}

else if(ex1[i]=='b'){

push(ps,binary(pop(ps)));

i++;

}

else if(ex1[i]=='d'){

push(ps,decimal(pop(ps)));

i++;

}

else i++;

}

return pop(ps);

}

int main(void)

{

myStack st1;

char exp1[100], exp2[100];

printf("\n수식을 띄어쓰기 없이 입력하시오\n\n(숫자 뒤에 b를 붙이면 이진수로, d를 붙이면 십진수로 변환합니다) : \n\n");

scanf("%s", exp1);

toPostfix(&st1, exp1, exp2);

printf("중위 표기식 : %s\n",exp1);

printf("후위 표기식 : %s\n",exp2);

printf("계산 결과는 다음과 같습니다 : %f\n",calc(&st1,exp2));

system("pause");

return 0;

}

 

반응형