Calc
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