[전자 Lab] 스택 계산기 알고리즘
학교에서 수행평가로 작성한 프로그램입니다~~
스택을 이용한 실수 사칙연산 계산기인데, 십진수를 이진수로, 이진수를 십진수로 변환하는 기능도 추가했습니다!!
#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;
}
'공학 > 전자공학' 카테고리의 다른 글
[학부 연구] Graphene Contact Resistance 최근 동향 (0) | 2023.02.25 |
---|---|
[학부 연구] Van der Waals Contact을 이용한 차세대 반도체 (0) | 2023.02.25 |
[전자 Lab] Stretchable Sensors in Form of Serpentine Structure (0) | 2023.02.24 |
[전자 Lab] TCAD를 사용한 P-N Junction Simulation (0) | 2023.02.24 |