✨컴공주✨ [1052682] · MS 2021 (수정됨) · 쪽지

2022-07-05 10:42:45
조회수 121

컴공 일기108

게시글 주소: https://orbi.kr/00057444833

스택이라는 자료구조로, 사칙 연산 계산기를 짠 프로그램입니다.  C++로 작성된 것이긴 하지만, 기본적인 골자는 C언어로 표현해보고 참조를 한 코드입니다. 제가 짠 것은 아니고, 인터넷에서 잘 쓰여진 코드를 몇 개만 짜깁기해서 가져왔어요. 예술에서는 흔히 표절이 금지되곤 하지만, 개발에서는 표절이 예술을 만들어 낼 수도 있답니다. 


가장 중요한 함수는 GetNextValue인 것 같습니다. 어제, 이 함수를 이해하는 데 8시간은 쓴 것 같거든요. 지금이야 이해 되지만, 굉장히 민감한 논리였습니다. (" " 띄어쓰기 또한 문자다) 덕택에, 문자열에 관한 논의들을 더 자세히 살펴볼 수 있는 기회가 되었네요.




Calculator.hpp


class Calculator {

private:

    char NUM[11] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'};

    enum symbol {

        LEFT_PARENTHESES = '(',

        RIGHT_PARENTHESES = ')',

        MULTIPLY = '*',

        DIVIDE = '/',

        PLUS = '+',

        MINUS = '-',

        SPACE = ' ',

        OPERAND

    };

 

public:

    unsigned int GetPriority(char op, int inStack);

    bool isPrior(char op1, char op2);

    bool isNum(char c);

};


Calculator.cpp


#include "Calculator.hpp"

 

unsigned int Calculator::GetPriority(char op, int inStack) {

    unsigned int priority = -1;

    switch(op) {

        case LEFT_PARENTHESES:

            if(inStack) priority = 3;

            else priority = 0;

            break;

        case MULTIPLY:

        case DIVIDE:

            priority = 1;

            break;

        case PLUS:

        case MINUS:

            priority = 2;

            break;

    }

 

    return priority;

}

 

bool Calculator::isPrior(char op1, char op2) {

    return (GetPriority(op1, 1) < GetPriority(op2, 0));

}

 

bool Calculator::isNum(char c) {

    for(int i=0;i<11;i++) {

        if(NUM[i] == c) return true;

    }

    return false;

}


unsigned int Calculator::GetNextValue(char *__EXPRESSION__, char *value, int *type) {

    unsigned int index = 0;

 

    for(index=0;__EXPRESSION__[index] != 0;index++) {

        if(isNum(__EXPRESSION__[index])) {

            *type = OPERAND;

            value[index] = __EXPRESSION__[index];

            if(!isNum(__EXPRESSION__[index+1])) break;

        } else {

            *type = __EXPRESSION__[index];

            value[index] = __EXPRESSION__[index];

            break;

        }

    }

 

    value[++index] = '\0';

    return index;

}


double Calculator::Calculate(char *postfix__EXPRESSION__) {

    LinkedListStack stack;

 

    char *value = (char*)malloc(strlen(postfix__EXPRESSION__)+1);

    unsigned int position = 0;

    unsigned int length = (unsigned int)strlen(postfix__EXPRESSION__)+1;

    int type = -1;

 

    double result = 0;

    char strResult[32];

 

    while(length > position) {

        position += GetNextValue(&postfix__EXPRESSION__[position], value, &type);

        if(type == SPACE || type == -1 || type == '\0') continue;

        if(type == OPERAND) {

            stack.Push(stack.CreateNode(value));

        } else {

            Node *op2 = stack.Pop();

            Node *op1 = stack.Pop();

 

            double tempResult = 0;

            memset(strResult, 0, 32);

 

            switch(type) {

                case MULTIPLY:

                    tempResult = atof(op1->Data) * atof(op2->Data);

                    break;

                case DIVIDE:

                    tempResult = atof(op1->Data) / atof(op2->Data);

                    break;

                case PLUS:

                    tempResult = atof(op1->Data) + atof(op2->Data);

                    break;

                case MINUS:

                    tempResult = atof(op1->Data) - atof(op2->Data);

                    break;

            }

 

            gcvt(tempResult, 10, strResult);

            stack.Push(stack.CreateNode(strResult));

 

            stack.DestroyNode(op1);

            stack.DestroyNode(op2);

        }

    }

 

    result = atof(stack.Pop()->Data);

 

    free(value);

    stack.DestroyStack();

 

    return result;

}


0 XDK (+0)

  1. 유익한 글을 읽었다면 작성자에게 XDK를 선물하세요.


  • 첫번째 댓글의 주인공이 되어보세요.