Search code examples
javadata-structuresstackpostfix-notation

Postfix evaluation (small bug)


In this problem on the input there is a statement given into a postfix notation, and my task is to evaluate the given statement. I completely understand the algorithm and i will post my solution below. But for some reason it works for these: 1 2 3 * + 5 -, 1 1 1 - - 1 + 1 +, 1 2 + ... etc. but it doesn't work when there are numbers with multiple digits like this one: 100 20 -. My solution (java):

public class PostFixEvaluation {

public static void main(String[] args) throws Exception{

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    String expression = br.readLine();
    char exp[] = expression.toCharArray();

    ArrayStack<Integer> op = new ArrayStack<Integer>(100);

    int vrednost = 0;
    int dolzina = 0;
    int suma = 0;
    int res=0;
    int convert = 0;
    char ch;

    for(int i=0; i < exp.length; i++){
        ch = exp[i];
        if(Character.isDigit(ch)){
            convert = (int)ch-'0';
            op.push(convert);
            convert = 0;
        }
        else if(exp[i] == '+'){
                int x = op.pop();
                int y = op.pop();
                vrednost = x + y;
                op.push(vrednost);
                vrednost = 0;
        }
        else if(exp[i] == '-'){
                int x = op.pop();
                int y = op.pop();
                vrednost = y - x;
                op.push(vrednost);
                vrednost = 0;
        }
        else if(exp[i] == '*'){
                int x = op.pop();
                int y = op.pop();
                vrednost = y * x;
                op.push(vrednost);
                vrednost = 0;
        }
        else if(exp[i] == '/'){
                int x = op.pop();
                int y = op.pop();
                vrednost = y/x;
                op.push(vrednost);
                vrednost = 0;
        }
    } 

    res = op.pop();

    System.out.println(res);


    br.close();

}
}

Solution

  • What you are doing here...

    for(int i=0; i < exp.length; i++){
        ch = exp[i];
        if(Character.isDigit(ch)){
            convert = (int)ch-'0';
            op.push(convert);
            convert = 0;
        }
    

    ...is reading a single character, and pushing it onto your stack of numbers. The problem is that you aren't checking to see whether that character is only the first digit of a number.

    If your code encounters "100 20 -", it will push "1", "0", "0", "2", "0" onto your number stack, instead of "100", "20".

    You need to rewrite your parsing code to grab the entire number, instead of checking each character individually.

    Update

    Regarding a better way to do that parsing, Java has some pretty good built-in String parsing tools.

    In this case, I would recommend using a Scanner to parse expression instead of converting it to a char[]. You can use methods like hasNext() and hasNextInt() to check whether there is more input, and whether that input is an int, and next() and nextInt() to read the next token.

    e.g.

    Scanner scanner = new Scanner(expression);
    while (scanner.hasNext()) {                     // while there more input...
        if (scanner.hasNextInt()) {                 // is the next token an int?
            int number = scanner.nextInt();         // read the next token as an integer
            op.push(number);
        } else {                                    // the next token is NOT an int
            String operator = scanner.next();       // read the next token as a String
            if (operator.equals("+")) {
                // same as before
            } else if (operator.equals("-")) {
                // same as before
            } else if (operator.equals("*")) {
                // same as before
            } else if (operator.equals("/")) {
                // same as before
            }
        }
    }