Infix to Postfix

I am trying to convert infix to postfix. For example: "20 + 2 * 3 + (2 * 8 + 5) * 4" → 20 2 3 * + 2 8 * 5 + 4 * + here is my code:

Stack<Character> s = new Stack<Character>();
String postfix = "";
boolean enter = true;
String infixExpr = "20 + 2 * 3     + (2*8 + 5)* 4";

for(int i = 0;i<infixExpr.length();i++){

    if(Character.isDigit(infixExpr.charAt(i)) == true){
        postfix = postfix + infixExpr.charAt(i);
    }
    if(infixExpr.charAt(i) == '+' || infixExpr.charAt(i) == '-'){
        if(s.isEmpty() == true){
            s.push(infixExpr.charAt(i));
        }
        else{
            if(s.peek() == '*' || s.peek() == '/' || s.peek() == '+' || s.peek() == '-'){
                while(s.isEmpty()== false){
                    postfix = postfix + s.pop();
                }
                s.push(infixExpr.charAt(i));
            }
            else{
                s.push(infixExpr.charAt(i));
            }
        }
    }
    if(infixExpr.charAt(i) == '*' || infixExpr.charAt(i) == '/' ){
        if(s.isEmpty() == true){
            s.push(infixExpr.charAt(i));
        }
        else{
            if(s.peek()== '+' || s.peek() == '-' || s.peek() == '('){
                s.push(infixExpr.charAt(i));
            }
            else if(s.peek() == '*' || s.peek() == '/'){
                while(s.isEmpty()== false){
                    postfix = postfix + s.pop();
                }
                s.push(infixExpr.charAt(i));
            }
        }
        if(infixExpr.charAt(i) == '('){
            s.push(infixExpr.charAt(i));
        }
        if(infixExpr.charAt(i) == ')'){
            while(enter){

                if(s.peek() == '('){
                    enter = false;
                }
                else{
                    postfix = postfix + s.pop();
                }
            }
        }
    }
}

      

As written at the top, I am supposed to get "20 2 3 * + 2 8 * 5 + 4 * +", but I get "2023 * + 28 * + 54" which is not correct and I have revised the code many times and yet I am not I see problems. It would be great if anyone could help.

+3


source to share


3 answers


Spaces

You are not putting spaces in your postfix variable. You are checking if the current character is one of the "interesting" characters (numbers, operators), but if it is not a space. As a result, if the current character is a space, you just skip it and you don't copy it to postfix.

Since the only things you put in the postfix are the characters you checked, you end up with no spaces.

You can solve it like this:

  • Add a boolean name inNumber

    , first set to true.
  • Whenever you process a digit, before adding it to postfix

    , check if it is true inNumber

    . If so, add a space first.
  • If you've just processed a digit, set the parameter inNumber

    to true.
  • If you are handling a statement, set inNumber

    to false.
  • When you add any operator to the stack, add a space first.

The idea behind this inNumber

is that digits belonging to the same number should not contain spaces between them. But if a digit is added to postfix

after we processed the statement in the previous round, then it belongs to the new number, so there must be a space in there.

So your digit handling code should look like this:

        if(Character.isDigit(infixExpr.charAt(i)) == true){
            if ( ! inNumber ) {
                postfix += " ";
            }
            postfix = postfix + infixExpr.charAt(i);
            inNumber = true;
        }

      

And in each if

one pointing to an operator, you must have inNumber = false

.

And every place where you add an operator to the postfix should look like this:

        postfix = postfix + " " + s.pop();

      


Handling parentheses



Another issue is processing ()

.

First, you put code that checks (

both )

inside if

for *

and /

. Of course, if the character at position i

is *

either /

, it is not (

or )

, so this code is never called.

So, you have to move if

for parentheses outside, to the same level if

for numbers and operators.

Also, the usage enter

is incorrect. If you have parentheses inside the parentheses, for example ( 3 + ( 5 + 7 ) )

, then the first time )

you get back in the parenthesis after 5

, which is fine. But then it enter

will become false and you will not handle the outer pair correctly. This is also true for (3 + 5 ) * ( 7 + 2 )

, because you don't install enter

in true

again after starting the program.

Instead of using, enter

you should put what's on the stack and check if it was (

:

        if(infixExpr.charAt(i) == '('){
            inNumber = false;
            s.push(infixExpr.charAt(i));
        }
        if(infixExpr.charAt(i) == ')'){
            inNumber = false;
            char popped;
            while ( ( popped = s.pop() ) != '(' ) {
                    postfix = postfix + " " + popped;
            }
        }        

      


Uncovered operators

Finally, you are done when you finish scanning the input. But for now, you still have operators waiting on the stack! You have to pull them all out and add to postfix

. So, after the loop, you should:

    while ( ! s.isEmpty()) {
        postfix += " " + s.pop();
    }

      


Additional notes:

  • It would be better and clearer if if

    you used the operator instead of using all of these operators switch

    .
  • It makes no sense to compare a boolean expression with true

    . The correct way to write if (s.isEmpty() == true)

    is simple if (s.isEmpty())

    , s.isEmpty() != true

    use instead ! s.isEmpty()

    .
  • You are not doing syntax checking. I'm not sure if this is because this is homework, but in real life you have to check that each one (

    matches )

    , that each operator has two operands, and also handles negative numbers it may have -

    at the beginning.
+2


source


The problem is that you are not adding spaces. However, you cannot just add space between each number. You have to make sure that no spaces are added between the digits of the integer. To solve this problem, I just added postfix += " ";

after if(infixExpr.charAt(i) == '+' || infixExpr.charAt(i) == '-')

and again after if(infixExpr.charAt(i) == '*' || infixExpr.charAt(i) == '/' )

. The logic behind this is that after you encountered the operator, you know that everything before the operator was a number. Now when I run the program, the output is 20 2 3 *+2 8 *+5 4

. There are a few more spaces to add between the statements, but I'll let you handle that.

Modified code:

    if(infixExpr.charAt(i) == '+' || infixExpr.charAt(i) == '-'){
        postfix += " ";

      



...

    if(infixExpr.charAt(i) == '*' || infixExpr.charAt(i) == '/' ){
        postfix += " ";

      

0


source


here is my code for your answer

#include<stack>
#include<iostream>
using namespace std;
bool high(char a,char b)
{
  if(b==' ')
    return true;
  else if(a==b)
    return false;
  else if(a=='/')
    return true;
  else if(a=='*'&&b!='/')
    return true;
  else if(b=='/')
    return false;
  else if(a!='/'&&b=='*')
    return false;
  else if(b=='-')
    return true;
  else if(a=='-'&&b!='(')
    return false;
  else if(b=='(')
    return true;
  else if(a=='(')
    return true;
  else if(a==')')
    return false;
}
main()
{
int k=0;
string s;
stack<char>s1;
s1.push(' ');
char ch;
while(cin>>ch)
{
    if(ch=='(')
    {
    k=1;
    s1.push(ch);}
    else if(ch>47&&ch<58)
    s.push_back(ch);
    else if(high(ch,s1.top()))
    s1.push(ch);
    else if(!high(ch,s1.top())&&ch!=')')
    {
        while(!s1.empty()&&!high(ch,s1.top()))
        {
            s.push_back(s1.top());
            s1.pop();
        }   
    s1.push(ch);}
    else if(ch==')')
    {
        while(!s1.empty()&&s1.top()!='(')
        {
            s.push_back(s1.top());
            s1.pop();
        }
        s1.pop();
        k=0;
    }

}
while(!s1.empty())
{
    s.push_back(s1.top());s1.pop();
}
cout<<s;
}

      

-1


source







All Articles