Calc
unknown
c_cpp
a year ago
11 kB
2
Indexable
#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 && memoryNumber == 1 ) { 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; }
Editor is loading...
Leave a Comment