I'm new to stackoverflow, and have final project for my Data Structures class in college. For my project, I am creating a calculator that takes a mathematical expression from input, such as (11-2)/3*(15+2/1)-6, and does two things:
1) Converts the expression from infix notation to postfix notation 2) Uses the postfix notation to evaluate the value of the expression
I have gotten fairly close to a final product, but my issue is that the program can only take numbers 0-9, as the way I currently have the code is that the conversion function evaluates the input as a string, and thus numbers greater than 9 (ie, double/triple digit numbers) will trip up the evaluation function. How can I detect these numbers as ints (or floats/doubles) and put them in a format (with the operators) that the evaluation function can deal with?
Additionally, I need to create exception class (incorrect parenthesis, division by zero, letters/non-operands/non-operators, etc). I have not learned much about what exception classes even are, so I'm not sure how I write these. I know it has to do with throw/catch functions, but any input is appreciated (or direction towards where I can find a simple explanation). I have pasted my code below:
#include <iostream>
#include <ctype.h>
#include <stack>
#include <ItemType.h>
using namespace std;
string getPostfix( string str );
double evaluate( string str );
bool hasPrecedence( char a, char b );
int main()
{
cout << "Welcome to the calculator!" << endl;
string infixString;
string postFixString;
bool valid = false;
cout << "Enter the expression you would like to evaluate: ";
getline( cin, infixString ); // get expression as string
postFixString = getPostfix( infixString ); // convert to postfix
cout << postFixString << endl;
cout << "The value of the given expression is: " << evaluate( postFixString ) << endl; // output evaluated expression
return 0;
}
string getPostfix( string str ) // function to convert infix to postfix
{
string postFixStr; // converted string
stack<char> stack; // stack for operators
for ( int i = 0; i < str.length(); i++ )
{
if ( isdigit( str[i] ) ) // if str[i] is a digit (0-9), add to postfix string
postFixStr += str[i];
else if ( str[i] == '(' ) // if str[i] is an opening parenthesis, push to stack
stack.push( str[i] );
else if ( str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' ) // if an operator...
{
if ( stack.empty() || stack.top() == '(' ) // ... push to stack if stack is empty or top of stack is opening parenthesis
{
stack.push( str[i] );
}
else if ( hasPrecedence( str[i], stack.top() ) ) // ... if the operator has higher precedence, push to stack
{
stack.push( str[i] );
}
else // ... if neither of the above cases, add operator already in stack to string, pop it, and push the new operator to stack
{
postFixStr += stack.top();
stack.pop();
stack.push( str[i] );
}
}
else if ( str[i] == ')' ) // ... if str[i] is closing parenthesis, add to string and pop until opening parenthesis is reached
{
while ( stack.top() != '(' )
{
postFixStr += stack.top();
stack.pop();
}
if ( stack.top() == '(' )
stack.pop();
}
}
while ( ! stack.empty() ) // after string has been iterated, add the remainder of the stack to the string
{
postFixStr += stack.top();
stack.pop();
}
return postFixStr;
}
double evaluate( string str ) // function to evaluate postfix expression
{
int op1, op2;
stack<int> stack;
for ( int i = 0; i < str.length(); i++ ) // iterate through postfix string
{
if ( isdigit( str[i] ) ) // if a digit, push to stack as int value
stack.push( str[i] - 48 );
else if ( str[i] == '+' ) // cases for different operators
{
op1 = stack.top(); // assign top int to op1
stack.pop(); // pop top
op2 = stack.top(); // assign next into to op2
stack.pop(); // pop top
stack.push( op1 + op2 ); // add op1 and op2, push result to stack
}
else if ( str[i] == '-' )
{
op1 = stack.top();
stack.pop();
op2 = stack.top();
stack.pop();
stack.push( op1 - op2 );
}
else if ( str[i] == '*' )
{
op1 = stack.top();
stack.pop();
op2 = stack.top();
stack.pop();
stack.push( op1 * op2 );
}
else if ( str[i] == '-' )
{
op1 = stack.top();
stack.pop();
op2 = stack.top();
stack.pop();
stack.push( op1 / op2 );
}
}
return stack.top(); // return final value
}
bool hasPrecedence( char a, char b ) // function to determine operator precedence
{
int aWeight, bWeight = 2;
if ( a == '*' || a == '/' )
aWeight = 2;
else
aWeight = 1;
return aWeight >= bWeight;
}
Thanks everyone for the replies. After looking into the solutions you all posted and gathering ideas from them, I found a very simple solution to my specific case.
In my getPostFix function, I added spaces after every character inserted into the postFixStr, and then using these spaces as delimiters, I was able to add this to the first "if" statement in my evaluate function:
if ( isdigit( str[i] ) )
{
double value = 0;
while ( i < str.length() && isdigit( str[i] ) ) // if a digit, push to stack as double value
{
value = ( value * 10 ) + ( str[i] - '0' );
i++;
}
stack.push(value);
}
Note, the * 10 is to move the previous value in as the 10's place (or 100's+ place), and the -'0'
is a slightly clearer version of the -49
that I had before to change the ascii value to the arithmetic value.
I hope this helps someone in the future!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.