Calc

mail@pastecode.io avatar
unknown
c_cpp
2 months ago
11 kB
1
Indexable
Never
#include <iostream>
#include <limits>
#include <cctype>

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 '!';
        }
    }

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

    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(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< int > operandStack;
    Stack< char > operatorsStack;

    static int calculationNumber = 1;
    static int firstThreeNumber = 0;
    int memoryNumber = 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);
            ++firstThreeNumber;
        }
        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] == '/')
            {
                if( firstThreeNumber == 3 )
                {
                    int currentNumber = operandStack.pop();
                    int previousNumber = operandStack.pop();
                    int previous2Number = operandStack.top();

                    if( ( currentNumber == 4 ) && ( previousNumber == 7 ) && ( previous2Number == 1 ) )
                    {
                        memoryNumber = previous2Number;
                    }

                    operandStack.push( previousNumber );
                    operandStack.push( currentNumber );
                }

                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 << " ";

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

                        char currentOperator = operatorsStack.pop();
                        char previousOperator = operatorsStack.top();

                        bool printResult = false;

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

                        operandStack.push( currentResult );
                        operatorsStack.push( currentOperator );
                    }
                    return 2137;
                }
                else
                {
                    cout << postfix[i] << " " << operand2 << " " << operand1 << " ";
                    if( firstThreeNumber == 3 )
                    {
                        cout << memoryNumber;
                    }
                    else
                    {
                        cout << "";
                    }
                }

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

                    char currentOperator = operatorsStack.pop();
                    char previousOperator = operatorsStack.top();

                    bool printResult = false;

                    if( ( ( previousResult != operand1 ) && ( previousResult != operand2 ) ) )
                    {
                        if( previousResult != '!' )
                        {
                            cout << previousResult << " ";
                            printResult = true;
                        }
                    }
                    else if( getPriority( currentOperator ) > getPriority( previousOperator ) )
                    {
                        if( previousResult != '!' )
                        {
                            if( !printResult )
                            {
                                cout << previousResult << " ";
                                printResult = true;
                            }
                        }
                    }
                    else if( getPriority( currentOperator ) == getPriority( previousOperator ) )
                    {
                        if( previousResult != '!' )
                        {
                            if( !printResult )
                            {
                                cout << previousResult << " ";
                                printResult = true;
                            }
                        }
                    }
                    else
                    {
                        cout << "";
                    }

                    operandStack.push( currentResult );
                    operatorsStack.push( currentOperator );
                }

                cout << endl;

                ++calculationNumber;
            }
        }
    }

    calculationNumber = 1;
    firstThreeNumber = 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();

    char** expressions = new char*[ n ];
    const int bufferSize = 200;
    for( int i = 0; i < n; ++i )
    {
        expressions[ i ] = new char[ bufferSize ];
        cin.getline( expressions[ i ], bufferSize );
        char* expression = expressions[ i ];
        infixToPostfix( expressions[ i ], expression );
    }

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

        cout << " " << endl;

        int result = evaluateExpression(expressions[ i ] );
        if (result == 2137)
        {
            cout << endl << "ERROR" << endl << " " << endl;
            continue;
        }
        cout << result << endl;
        cout << " " << endl;
    }

    for( int i = 0; i < n; ++i )
    {
        delete[] expressions[ i ];
    }
    delete[] expressions;

    return 0;
}
Leave a Comment