Calc

 avatar
unknown
c_cpp
a year ago
9.2 kB
7
Indexable
#include <iostream>
#include <limits>

using namespace std;

template< typename T >
class Stack
{
public:
    Stack()
    {
        size = 20;
        items = new T[ size ];
        top_index = -1;
    }

    ~Stack()
    {
        delete[] items;
    }

    void push( T value )
    {
        if( !full() )
        {
            ++top_index;
            items[ top_index ] = value;
        }
        else
        {
            cout << "Stack is full!" << endl;
            return;
        }
    }

    T pop()
    {
        if( !empty() )
        {
            T popped = items[ top_index ];
            --top_index;
            return popped;
        }
        else
        {
            // cout << "Stack is empty!" << endl;
            return '\0';
        }
    }

    T top()
    {
        if( !empty() )
        {
            return items[ top_index ];
        }
        else
        {
            // cout << "Stack is empty!" << endl;
            return '\0';
        }
    }

    bool empty() const
    {
        return top_index == -1;
    }

    bool full() const
    {
        return top_index == size - 1;
    }

private:
    T* items;
    int top_index;
    int size;
};

bool isOperator(char c)
{
    return (c == '+' || c == '-' || c == '*' || c == '/' || c == 'N');
}

int getPriority(char op)
{
    if (op == 'N')
    {
        return 3;
    }
    else if (op == '*' || op == '/')
    {
        return 2;
    }
    else if (op == '+' || op == '-')
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

void infixToPostfix(const char* infix, char* postfix)
{
    Stack< char > operatorStack;
    int k = 0;

    for (int i = 0; i < infix[i]; ++i)
    {
        if (infix[i] == ' ' || infix[i] == ',')
        {
            continue;
        }
        else if (isdigit(infix[i]))
        {
            postfix[k++] = infix[i++];
            for (int j = i; ; j++)
            {
                if (isdigit(infix[j]))
                {
                    postfix[k++] = infix[j];
                    i++;
                }
                else
                {
                    break;
                }
            }
        }
        else if (infix[i] == '(')
        {
            operatorStack.push(infix[i]);
        }
        else if (infix[i] == ')')
        {
            while (!operatorStack.empty() && operatorStack.top() != '(')
            {
                postfix[k++] = operatorStack.top();
                operatorStack.pop();
            }
            operatorStack.pop();
        }
        else if (isOperator(infix[i]))
        {
            postfix[ k++ ] = ' ';
            while (!operatorStack.empty() && getPriority(operatorStack.top()) >= getPriority(infix[i]))
            {
                postfix[ k++ ] = operatorStack.top();
                operatorStack.pop();
            }
            operatorStack.push(infix[i]);
        }
    }

    while (!operatorStack.empty())
    {
        postfix[k++] = operatorStack.top();
        operatorStack.pop();
    }

    postfix[k] = '\0';
}

int calculateOperation(int a, int b, char op)
{
    switch (op)
    {
        case '+':
            return a + b;
        case '-':
            return a - b;
        case '*':
            return a * b;
        case '/':
            if (b == 0)
            {
                return 2137;
            }
            else
            {
                return a / b;
            }
        case 'N':
            return -b;
        default:
            return 0;
    }
}

int evaluateExpression(char* postfix)
{
    Stack< char > operandStack;
    Stack< char > operatorsStack;

    static int calculationNumber = 1;
//    Stack< int > calculationStack;
//    int calcIndex = 0;

    for (int i = 0; postfix[i]; ++i)
    {
        if (postfix[i] == ' ' || postfix[i] == ',')
        {
            continue;
        }
        else if (isdigit(postfix[i]))
        {
            int operand = 0;
            while (isdigit(postfix[i]))
            {
                operand = operand * 10 + (postfix[i] - '0');
                ++i;
            }
            --i;
            operandStack.push(operand);
        }
        else if (isOperator(postfix[i]))
        {
            if (postfix[i] == 'N')
            {
                int operand3 = operandStack.top();
                operandStack.pop();
                int result = calculateOperation(0, operand3, postfix[i]);
                operandStack.push(result);
                cout << postfix[i] << " " << operand3 << " " << endl;
            }
            else if (postfix[i] == '+' || postfix[i] == '-' || postfix[i] == '*' || postfix[i] == '/')
            {
                operatorsStack.push( postfix[ i ] );

                int operand2 = operandStack.top();
                operandStack.pop();
                int operand1 = operandStack.top();
                operandStack.pop();
                int result = calculateOperation(operand1, operand2, postfix[ i ] );
                operandStack.push(result);
                if (result == 2137)
                {
                    cout << postfix[i] << " " << operand2 << " " << operand1 << " ";
                    return 2137;
                }
                else
                {
                    cout << postfix[i] << " " << operand2 << " " << operand1 << " ";
                }

                if( calculationNumber >= 2 )
                {
                    int currentResult = operandStack.pop();
                    int previousResult = operandStack.top();

                    if( ( previousResult != operand1 ) && ( previousResult != operand2 ) )
                    {
                        if( previousResult != '\0' )
                        {
                            cout << previousResult << " ";
                        }
                    }
                    else
                    {
                        cout << "";
                    }

                    operandStack.push( currentResult );
                }

//                if( calculationNumber >= 2 )
//                {
//                    char currentOperator = operatorsStack.pop();
//                    char previousOperator = operatorsStack.top();
//                    if( ( getPriority( currentOperator ) > getPriority( previousOperator ) ) )
//                    {
//                        int currentResult = operandStack.pop();
//                        int previousResult = operandStack.top();
//                        calculationStack.push( previousResult );
//                        ++calcIndex;
//                        operandStack.push( currentResult );
//                    }
//                    else if( ( getPriority( currentOperator ) < getPriority( previousOperator ) )  )
//                    {
//                        if( !calculationStack.empty() )
//                        {
//                            calculationStack.pop();
//                            --calcIndex;
//                        }
//                    }
//                    operatorsStack.push( currentOperator );
//                }
//
//                for( int j = 0; j < calcIndex; ++j )
//                {
//                    if( !calculationStack.empty() )
//                    {
//                        cout << calculationStack.top() << " ";
//                    }
//                }

                cout << endl;

                ++calculationNumber;
            }
        }
    }

    calculationNumber = 0;

    return operandStack.top();
}

int main()
{
    // char expression[] = "4 - 3 - 6 + 6 / 7 / 4 .";
    // char expression[] = "6 / 3 + 8 - 4 - 8 .";
    // char expression[] = "N 12 + 2 * ( 3 * 4 + 10 / 5 ).";

    int n;

    cin >> n;
    cin.ignore( numeric_limits<streamsize>::max(), '\n' );
    cin.clear();

    for( int i = 0; i < n; ++i )
    {
        const int bufferSize = 200;
        char expression[ bufferSize ];

        cin.getline( expression, bufferSize );


        char postfix[ 200 ];
        infixToPostfix( expression, postfix );

        for( int j = 0; postfix[ j ] != '\0'; ++j )
        {
            if( isOperator( postfix[ j ] ) )
            {
                cout << postfix[ j ] << ' ';
            }
            else if( isdigit(postfix[ j ] ) && isOperator( postfix[ j + 1 ] ) )
            {
                cout << postfix[ j ];
                cout << " ";
            }
            else
            {
                cout << postfix[ j ];
            }
        }

        cout << " " << endl;


        int result = evaluateExpression(postfix);
        if (result == 2137)
        {
            cout << "ERROR" << endl << " " << endl;
            continue;
        }
        cout << result << endl;
        cout << " " << endl;
    }

    return 0;
}
Editor is loading...
Leave a Comment