Calc
unknown
c_cpp
2 years ago
12 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 '!';
}
}
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(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 << " ";
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;
}
}
else
{
cout << "";
}
// if( getPriority( currentOperator ) > getPriority( previousOperator ) && !previousResult )
// {
// if( previousResult != '!' )
// {
// cout << previousResult << " ";
// previousResult = true;
// }
// }
// else
// {
// cout << "";
// }
operandStack.push( currentResult );
operatorsStack.push( currentOperator );
}
return 2137;
}
else
{
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 << " ";
printResult = true;
}
}
else
{
cout << "";
}
if( getPriority( currentOperator ) > getPriority( previousOperator ) )
{
if( previousResult != '!' )
{
if( !printResult )
{
cout << previousResult << " ";
previousResult = true;
}
}
}
else
{
cout << "";
}
if( getPriority( currentOperator ) == getPriority( previousOperator ) )
{
if( previousResult != '!' )
{
if( !printResult )
{
cout << previousResult << " ";
previousResult = true;
}
}
}
else
{
cout << "";
}
operandStack.push( currentResult );
operatorsStack.push( currentOperator );
}
// 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 << endl << "ERROR" << endl << " " << endl;
continue;
}
cout << result << endl;
cout << " " << endl;
}
return 0;
}
Editor is loading...
Leave a Comment