티스토리 뷰


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define STKSIZ 30                                                   // 스텍 사이즈
#define ARYSIZ 30                                                   // 문자열 배열 사이즈
#define INULL -100                                                  // int는 NULL을 0으로 인식하기에 Int용 NULL을 만듬       
void inputData(int*);                                                // 데이타 삽입
void itoo(int);                                                                // 치환된 연산자를 원래대로 출력해준다.
void postfix(int*,int*);                                        // postfix정렬
void pntAry(int*);                                                        // 배열의 내용을 출력한다.
int oper(char);                                                                // int 배열에 넣기 위한 연산자 치환함수
int operOrder(int);                                                        // 연산자의 우선순위를 출력해 준다.
float calculation(int *ptfx);                                // postfix로 정렬된 데이타들을  계산
float arithmetics(float,float,int);                        // 두개의 데이터와 하나의 연산자를 받아 사친연산후 결과값 리턴
//스텍 관련
void push(float*,int*,float);                                // 스텍에 데이터를 삽입한다.
float pop(float*,int*);                     // 스텍에 데이터를 꺼낸다.
//초기화 함수들 
void rstChrAry(char*,int);                                        // char배열을 NULL로 초기화 해준다.
void rstIntAry(int*,int);                                        // int배열을 INULL로 초기화 해준다.

 

void main(void){

        int pt = 0, alPt = 0;                                // 스텍 포인터의 위치 //pt = 0, algePt = alge[]포인터
        int alge[ARYSIZ];                                        // 전체적인 수식이 들어가는 배열
        int ptfx[ARYSIZ];                                        // postfix 배열 

      //  while(1){
                rstIntAry(alge,ARYSIZ);     // 수식이 들어갈 배열 리셋
                rstIntAry(ptfx,ARYSIZ);     // postfix 정렬될 배열 리셋
               
                inputData(alge);            // 수식 삽입
                postfix(alge,ptfx);         //postfix

                printf("\n<POSTFIX>\n");
                pntAry(ptfx);               //postfix 내용 출력       
                                                                                        // postfix를 계산하여 결과값 출력
                                printf("\n= %.3f\n",calculation(ptfx));       
      //  }
}

void inputData(int *alge){                        // 수식을 삽입한다.
       
        int i=0, j=0, k=0;                //str[i], temp[j], alge[k]
        char temp[ARYSIZ];
        char str[ARYSIZ];        // 문자열을 받기 위한 배열
       
        scanf("%s",str);
       
        while(1){        //문자열에 들어간 연속된 숫자들은 하나로 모아준다.
               
                if(str[i] <='9' && str[i] >='0' && NULL != str[i]){                // str[i]가 숫자라면
                        temp[j++] = str[i++];                                               // temp스택에 넣어 쌓는다.
                }else{                                                                           // str[i]가 숫자가 아니라면(연산자라면)
                        alge[k++] = (int)atoi(temp);                                      //[연산자가 먼저 오지 않을테니깐] temp의 내용을 int로 바꾼뒤 alge[]에 저장
                        alge[k++] = oper(str[i++]);                                        // 연산자치환해서 alge에 저장
                        j=0;
                        rstChrAry(temp,ARYSIZ);                                                        //스텍을 초기화 한다.
                        if(NULL==str[i])break;
                }
        }
       
        alge[k] = INULL;                                                                                                // 다 마치면 alge[] 마지막 값에 널 입력
}

void postfix(int *alge, int *ptfx){                                                                                //식[], postfix[]
       
        int i = 0, j = 0, k = 0, pt = 0, temp;       
        float operStack[STKSIZ];                                                                                // 연산자를 받기 위한 스텍 배열
       
        while(INULL!=alge[i]){                                                                                        // 식을 끝까지 읽는다.       
               
                if(0<=alge[i]){                                                                                        // 슷자라면
                        ptfx[j++] = alge[i++];
                }else{                                                                                                        // 연산자라면
                        temp = alge[i++];                                                                // temp에 연산자를 넣는다.
                       
                        //스텍에 데이타가 있고, 스텍에 있는것이 우선 순위가 같거나 높다면 pop
                        if((pt!=0) && (operOrder((int)operStack[pt-1]) >= operOrder(temp))){       
                                ptfx[j++] = (int)pop(operStack,&pt);
                        }
                       
                        ptfx[j++] = alge[i++];                                                        // 다음 숫자를 저장한다.
                       
                        if(10==operOrder(temp)){                                                // 만약 temp가 우선순위 연산자라면
                                ptfx[j++] = temp;                                                // temp를 postfix[]에 저장
                               
                        }else{                                          // 우선 순위 연산자가 아니라면
                                push(operStack,&pt,(float)temp);        // temp를 stack에 저장
                        }
                }
               
        }
        if(0!=pt) ptfx[j++] = (int)pop(operStack,&pt);                                        // 스텍에 연산자가 남아있다면 pop;
}

void pntAry(int *arge){                                                                                                        // 배열의 내용을 출력한다.

        int i=0;       
        if(INULL==arge[i]){printf("empty!");} //test
        while(INULL!=arge[i]){
                itoo(arge[i++]);                                                                                // 치환된 연산자를 원래대로 출력해준다.
        }
}
void itoo(int i){                                                                                                                // 치환된 연산자를 원래대로 출력해준다.
        switch(i){
        case -10: printf("* "); break;
        case -20: printf("/ "); break;
        case -30: printf("+ "); break;
        case -40: printf("- "); break;
        default: printf("%d ",i);
        }       
}

int oper(char opr){                                                                                                                //int 배열에 넣기 위한 연산자 치환함수
        // *,/,+,- 각각 -10,-20,-30,-40 으로 치환
        int i;
        switch(opr){
               
        case '*': i = -10; break;
        case '/': i = -20; break;
        case '+': i = -30; break;
        case '-': i = -40; break;
        case NULL : i = -100; break;
        }       
        return i;
}

float pop(float *stack, int *pt){
       
        float data;
        if(*pt<=0){                               
                printf("stack is empty\n");
                return 0;
        }
        data = stack[--(*pt)];
//        printf("\npop[%d]!\n",data);
        return data;
}

void push(float *stack, int *pt, float data){

        if(*pt > STKSIZ){                                // [예외처리]스텍이 가득차면
                printf("stack is full!\n");              // error 메세지
                return;
        }
        stack[(*pt)++] = data;
}

// postfix 정렬된 수식을 계산하여 결과값을 리턴한다.
float calculation(int *ptfx){
       
        int i = 0, pt=0;
        float calStack[STKSIZ], a, b, c, result = 0;

        while(INULL!=ptfx[i]){
                if(0<=ptfx[i]){                                                        //숫자라면
                        push(calStack, &pt, (float)ptfx[i++]);        //push
                }else{                                                                        //연산자라면
                        a = pop(calStack, &pt);         // 스텍에 들어있는
                        b = pop(calStack, &pt);         // 수 2개를 pop해서
                        c = arithmetics(a,b,ptfx[i++]); // 연산자에 맞는 사칙연산
                        push(calStack, &pt, c);                        // 결과값을 스텍에 push
                }
       
        }
        return calStack[0];                                                                // 최종 결과값은 stack 가장 하단에 남는다.
}

float arithmetics(float a, float b, int opr){                        // 사칙연산

        float result;

        switch(opr){                                                                        //인트배열을 해석한다.
        case -10:        result = b*a; break;                        //*
        case -20:        result = b/a; break;                        ///
        case -30:        result = b+a; break;                        //+
        case -40:        result = b-a; break;                        //-
        }

        return result;
}

int operOrder(int dt){                                // 우선순위 입력받은 연산자의 우선순위를 리턴한다.
        int opr;

        switch(dt){
        case -10:                                                                        //*
        case -20: opr = 10; break;                                        ///
        case -30:                                   //+
        case -40: opr =  9; break;                                        //-
        }

        return opr;
}

// char배열 리셋
void rstChrAry(char *temp, int sz){
       
        int i = 0;
        for(i=0;i<sz;i++){
                temp[i] = NULL;
        }
}

// int배열 리셋
void rstIntAry(int *temp, int sz){
       
        int i = 0;
        for(i=0;i<sz;i++){
                temp[i] = INULL;
        }
}

 

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함