My lecturer gave me an assignment to create a program to convert and infix expression to postfix using Stacks. I've made the stack classes and some functions to read the infix expression.
But this one function, called convertToPostfix(char * const inFix, char * const postFix)
which is responsible to convert the inFix expression in the array inFix to the post fix expression in the array postFix using stacks, is not doing what it suppose to do. Can you guys help me out and tell me what I'm doing wrong?
The following is code where the functions to convert from inFix to postFix is and convertToPostfix(char * const inFix, char * const postFix)
is what I need help fixing:
void ArithmeticExpression::inputAndConvertToPostfix()
{
char inputChar; //declaring inputChar
int i = 0; //inizalize i to 0
cout << "Enter the Arithmetic Expression(No Spaces): ";
while( ( inputChar = static_cast<char>( cin.get() ) ) != '\n' )
{
if (i >= MAXSIZE) break; //exits program if i is greater than or equal to 100
if(isdigit(inputChar) || isOperator(inputChar))
{
inFix[i] = inputChar; //copies each char to inFix array
cout << inFix[i] << endl;
}
else
cout << "You entered an invalid Arithmetic Expression\n\n" ;
}
// increment i;
i++;
convertToPostfix(inFix, postFix);
}
bool ArithmeticExpression::isOperator(char currentChar)
{
if(currentChar == '+')
return true;
else if(currentChar == '-')
return true;
else if(currentChar == '*')
return true;
else if(currentChar == '/')
return true;
else if(currentChar == '^')
return true;
else if(currentChar == '%')
return true;
else
return false;
}
bool ArithmeticExpression::precedence(char operator1, char operator2)
{
if ( operator1 == '^' )
return true;
else if ( operator2 == '^' )
return false;
else if ( operator1 == '*' || operator1 == '/' )
return true;
else if ( operator1 == '+' || operator1 == '-' )
if ( operator2 == '*' || operator2 == '/' )
return false;
else
return true;
return false;
}
void ArithmeticExpression::convertToPostfix(char * const inFix, char * const postFix)
{
Stack2<char> stack;
const char lp = '(';
stack.push(lp); //Push a left parenthesis ‘(‘ onto the stack.
strcat(inFix,")");//Appends a right parenthesis ‘)’ to the end of infix.
// int i = 0;
int j = 0;
if(!stack.isEmpty())
{
for(int i = 0;i < 100;){
if(isdigit(inFix[i]))
{
postFix[j] = inFix[i];
cout << "This is Post Fix for the first If: " << postFix[j] << endl;
i++;
j++;
}
if(inFix[i] == '(')
{
stack.push(inFix[i]);
cout << "The InFix was a (" << endl;
i++;
//j++;
}
if(isOperator(inFix[i]))
{
char operator1 = inFix[i];
cout << "CUrrent inFix is a operator" << endl;
if(isOperator(stack.getTopPtr()->getData()))
{
cout << "The stack top ptr is a operator1" << endl;
char operator2 = stack.getTopPtr()->getData();
if(precedence(operator1,operator2))
{
//if(isOperator(stack.getTopPtr()->getData())){
cout << "The stack top ptr is a operato2" << endl;
postFix[j] = stack.pop();
cout << "this is post fix " << postFix[j] << endl;
i++;
j++;
// }
}
}
else
stack.push(inFix[i]);
// cout << "Top Ptr is a: "<< stack.getTopPtr()->getData() << endl;
}
for(int r = 0;r != '\0';r++)
cout << postFix[r] << " ";
if(inFix[i] == ')')
{
while(stack.stackTop()!= '(')
{
postFix[j] = stack.pop();
i++;
j++;
}
stack.pop();
}
}
}
}
Note the function convertToPostfix was made using this algorithm:
- Push a left parenthesis ‘(‘ onto the stack.
- Append a right parenthesis ‘)’ to the end of infix.
While the stack is not empty, read infix from left to right and do the following:
- If the current character in infix is a digit, copy it to the next element of postfix.
- If the current character in infix is a left parenthesis, push it onto the stack.
If the current character in infix is an operator,
- Pop operator(s) (if there are any) at the top of the stack while they have equal or higher precedence than the current operator, and insert the popped operators in postfix.
- Push the current character in infix onto the stack.
- If the current character in infix is a right parenthesis
- Pop operators from the top of the stack and insert them in postfix until a left parenthesis is at the top of the stack.
- Pop (and discard) the left parenthesis from the stack.
Operator Precedence is the problem in this case. The correct operator precedence in descending order is:
In the question above consider the precedence function
for each value in operator1 corresponding value of operator2 should be checked for precedence, according to OPERATOR PRECEDENCE TABLE mentioned above. Do not return any value without proper comparison.
Here's mine using C with multiple digits evaluation.
So there are a number of problems with your code. I'll post what (should be) a corrected solution, which has copious comments to explain what's happening and where you've made mistakes. A few things up front:
I'll use
std::string
instead ofchar *
because it makes things much cleaner, and honestly, you should be using it inC++
unless you have a very good reason not to (such as interoperability with aC
library). This version also returns astring
instead of taking achar *
as a parameter.I'm using the stack from the standard library,
<stack>
, which is slightly different to your home-rolled one.top()
shows you the next element without removing it from the stack, andpop()
returnsvoid
, but removes the top element from the stack.It's a free function, not part of a class, but that should be easy to modify - it's simply easier for me to test this way.
I'm not convinced your operator precedence tables are correct, however, I'll let you double check that.
C++ implementation is given below:
This is basically a comment to the answer from Yuushi.
precedence(rightOp, leftOp)
). Then you should document what the result means - right now you return true ifa rOp b lOp c == (a rOp b) lOp c
(yes, the operator order doesn't match what you call - "+" and "-" are not the same in both orders for example).a - b * c
your output isa b c
and the stack is[- *]
. now you read a+
, and you need to pop both operators, resulting ina b c * -
. I.e., the inputa - b * c + d
should result ina b c * - d +
Update: appended complete solution (based on Yuushi's answer):