Hi all - I am writing a program that uses two classes: One class is the InfixtoPostfix, which is actually the class that changes expressions from infix to postfix. (Example: ( A + B ) * ( C - D ) to
A B + C D -*. The second class, PostfixEval, is supposed to calculate the expression.

My problem is that my code works easily enough for expressions with values (Example: ( 1 + 2 ) * ( 3 - 4 ), but the file we have to read in is variables. We were given a list of values (Example: A = 12, B = 22, C = -5, etc.), to assign to the variables and hard code. So I guess my question is how can I edit my code so that it assigns a value to the variable and calculates the postfix expressions?

Here's my infix to postfix class:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

public class InfixtoPostfix {
    public static final String operators = "+-*/";
    public static final String left = "(";
    public static final String right = ")";

        public static void main(String[] args){
            File file = new File("infix.txt");

            try{
                Scanner sc = new Scanner(file);
                while(sc.hasNextLine()){
                    String line = sc.nextLine();
                    System.out.println("Postfix:" + " " + convert(line));
                    String finalResult = convert(line);
                    System.out.println("Result:" + " " + PostfixEval.evaluate(finalResult));
                }
            }
            catch(FileNotFoundException e){
                e.printStackTrace();
            }
        }

        public static String convert(String str){
            String conversion = "";
            Stack<Character> stuff = new Stack<Character>();
            for(int i = 0; i < str.length(); i++){
                char c = str.charAt(i);

                if(c==('+')||c==('*')||c==('-')||c==('/')){

                    while(!stuff.empty() && isLower(stuff.peek(), c))
                            conversion+=stuff.pop();
                        stuff.push(c);
                    }
                    else if(c=='('){
                        stuff.push(c);
                    }
                    else if(c==')'){
                        while(!stuff.peek().equals('('))
                            conversion += stuff.pop();
                        stuff.pop();
                }
                    else
                        conversion += c;

            }
            while(!stuff.empty())
            conversion+=stuff.pop();
            return conversion;
        }
        public static boolean isLower(char c1, char c2){
            if((c1 == '+' || c1 == '-') && (c2 == '*' || c2 == '/'))
                return true;
            return false;
        }

}

and here is my postfix evaluator class

import java.util.Stack;

public class PostfixEval{


    public static Double evaluate(String postfix){
        Stack<Double> s = new Stack<Double>();
        char[] chars = postfix.toCharArray();
        int N = chars.length;

        for(int i = 0; i < N; i++){
            char ch = chars[i];

            if(isOperator(ch)){
                switch(ch){
                case '+': s.push(s.pop() + s.pop());     break;
                case '*': s.push(s.pop() * s.pop());     break;
                case '-': s.push(-s.pop() + s.pop());    break;
                case '/': s.push(1 / s.pop() * s.pop()); break;
                }
            }else if(Character.isDigit(ch)) {
                s.push(0.0);
                while (Character.isDigit(chars[i]))
                    s.push(10.0 * s.pop() + (chars[i++] - '0'));
        }
        }
            if (!s.isEmpty()) 
                return s.pop();
            else
                return 0.0;

        }

        private static boolean isOperator(char ch) {
            return ch == '*' || ch == '/' || ch == '+' || ch == '-';
        }

}

Hmm that is tricky one, because you don't know how much variable need to be assigned, you can build it like compailer, with toknes and grammar but that is complicated. You can try to add new method who goes through input find first "=" and then assign values to some array, when you need to calculate (+,-,*,...) you can just grab values from array and calculate whatever you need...

When parsing the infix you can parse for parens, operators and numbers like you do now, but also parse for alphabetic tokens ie variable names (looks like you can assume single letter names?). Treat them just like numbers when converting to postfix.
In the evaluator, when you get an variable replace it with its numeric value and evaluate as usual. If the variable names/values are fixed you can hard code that; in general you could use a Map with the name as key and the current value.

I'm a little confused. Would I do that within the evaluator method itself? The variable names and values are fixed, I just can't figure out the logic behind the code.

Figured it out.

Here is the fixed Postfixeval class for anyone interested. It works as long as the parantheses are balanced in the equations.

import java.util.Stack;

public class PostfixEval{

    public static Double translate(String postfix){
        Stack<Double> translateStack = new Stack<Double>();
        char[] chars = postfix.toCharArray();
        int H = chars.length;

        for(int i = 0; i < H; i++){
            char ch = chars[i];

            if(isOperator(ch)){
                switch(ch){
                case '+': translateStack.push(translateStack.pop() + translateStack.pop());     break;
                case '*': translateStack.push(translateStack.pop() * translateStack.pop());     break;
                case '-': translateStack.push(-translateStack.pop() + translateStack.pop());    break;
                case '/': translateStack.push(1 / translateStack.pop() * translateStack.pop()); break;
                }
            } else if(!Character.isDigit(ch)){
                if(ch == 'A'){
                    double Aval = 10;
                    translateStack.push(Aval);
                } else if (ch == 'B'){
                    double Bval = 42;
                    translateStack.push(Bval);
                } else if (ch == 'C'){
                    double Cval = 11;
                    translateStack.push(Cval);
                } else if (ch == 'D'){
                    double Dval = -5;
                    translateStack.push(Dval);
                } else if (ch == 'E'){
                    double Eval = 7;
                    translateStack.push(Eval);
                } else if (ch == 'F'){
                    double Fval = 83;
                    translateStack.push(Fval);
                } else if (ch == 'G'){
                    double Gval = 4;
                    translateStack.push(Gval);
                } else if (ch == 'H'){
                    double Hval = -21;
                    translateStack.push(Hval);
                } else if (ch == 'I'){
                    double Ival = 39;
                    translateStack.push(Ival);
                }
            }
        }
        if (!translateStack.isEmpty()) 
            return translateStack.pop();
        else
            return 0.0;
    }


        private static boolean isOperator(char ch) {
            return ch == '*' || ch == '/' || ch == '+' || ch == '-';
        }

}

Edited 2 Years Ago by bigredaltoid

Maybe I'm missing something... but isn't this obvious. If your infix/postfix is working with regular integers why not just do the the alphabet substitution right at the beginning!?

The only thing I would be concerned about are unary type operators such as --5 become +5. But if this is an assignment I doubt you would need to worry about such cases.

This article has been dead for over six months. Start a new discussion instead.