Postfix Calculator Java

38,616

Solution 1

There are several things you need to change, which you can do step by step.

  1. Declare your Stack to contain Integers rather than Characters.
  2. In the code that reads the input, rely on Strings instead of Characters.
  3. Parse operands using Integer.parseInt(). This will convert Strings to Integers. (Actually, it converts them to ints, but in your case this difference doesn't matter.)
  4. Set the scanner delimiter using Scanner.useDelimiter() to \s+, this will match a sequence of any whitespace characters.

There are of course countless of other ways to process your input but I tried to give you an idea of how to change your existing code to do what it needs to do.

Solution 2

In order to tokenize you can use the String.split() with a single space as a separator;

String[] inputs = input.split(" ");

Here is a full solution that I've just written that which uses a Stack implementation based on a singly linked list in order to make a postfix calculator;

A - PostFixCalculator

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class PostFixCalculator {

    private static final String ADD = "+"; 
    private static final String SUB = "-";
    private static final String MUL = "*";
    private static final String DIV = "/";

    public void calculateFile(String fileName) throws IOException {
        BufferedReader br = null;
        StringBuilder sb = null;
        try {
            FileReader fileReader = new FileReader(fileName);
            br = new BufferedReader(fileReader);

            sb = new StringBuilder();
            String line = br.readLine();

            while (line != null) {
                sb.append(line);
                line = br.readLine();
            }

            String input = sb.toString();
            System.out.println(input + " = " + calculate(input));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            br.close();
        }
    }

    private int calculate(String input) {
        SinglyLinkedListStack<Integer> stack = new SinglyLinkedListStack<>();

        String[] inputs = input.split(" ");

        return handleCalculation(stack, inputs);
    }

    private static int handleCalculation(SinglyLinkedListStack<Integer> stack, String[] el) {
        int operand1, operand2;

        for(int i = 0; i < el.length; i++) {
            if( el[i].equals(ADD) || el[i].equals(SUB) || el[i].equals(MUL) || el[i].equals(DIV) ) {
                operand2 = stack.pop();
                operand1 = stack.pop();
                switch(el[i]) {
                    case ADD: {
                        int local = operand1 + operand2;
                        stack.push(local);
                        break;
                    }

                    case SUB: {
                        int local = operand1 - operand2;
                        stack.push(local);
                        break;
                    }

                    case MUL: {
                        int local = operand1 * operand2;
                        stack.push(local);
                        break;
                    }

                    case DIV: {
                        int local = operand1 / operand2;
                        stack.push(local);
                        break;
                    }
                }
            } else {
                stack.push(Integer.parseInt(el[i]));
            }
        }

        return stack.pop();
    }

}

B - SinglyLinkedListStack

public class SinglyLinkedListStack<T> {

    private int size;
    private Node<T> head;

    public SinglyLinkedListStack() {
        head = null;
        size = 0;
    }

    public void push(T element) {
        if(head == null) {
            head = new Node(element);
        } else {
            Node<T> newNode = new Node(element);
            newNode.next = head;
            head = newNode;
        }

        size++;
    }

    public T pop() {
        if(head == null)
            return null;
        else {
            T topData = head.data;

            head = head.next;
            size--;

            return topData;
        }
    }

    public T top() {
        if(head != null)
            return head.data;
        else
            return null;
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    private class Node<T> {
        private T data;
        private Node<T> next;

        public Node(T data) {
            this.data = data;
        }

    }

}

C - Demo

import java.io.IOException;

public class PostFixCalculatorDemo {
    public static void main(String[] args) throws IOException {
        PostFixCalculator calc = new PostFixCalculator();
        calc.calculateFile("postfix.txt");
    }
}

D - Sample Input File: "postfix.txt"

6 5 2 3 + 8 * + 3 + * 

E - Demo Output

6 5 2 3 + 8 * + 3 + *  = 288
Share:
38,616
Jmamz06
Author by

Jmamz06

Updated on August 11, 2020

Comments

  • Jmamz06
    Jmamz06 over 3 years

    Ok so I have to read in a postfix expression from a file. The postfix expression must have spaces to separate each operator or operand. What I have so far works only if there is no spaces between the operators or operands in the input file. (i.e. if the file has 12+ the result I get is 3.) In order to do this I think that I need to tokenize the input, but I am not sure how. This is what I have so far. Thank you for any responses.

    import java.util.*;
    import java.io.*;
    public class PostfixCalc{
    public static void main (String [] args) throws Exception {
    File file = new File("in.txt");
    Scanner sc = new Scanner(file);
    String input = sc.next();
    Stack<Integer> calc = new Stack<Integer>();
    while(sc.hasNext()){
    for(int i = 0; i < input.length(); i++){
        char c = input.charAt(i);
        int x = 0;
        int y = 0;
        int r = 0;
        if(Character.isDigit(c)){
           int t = Character.getNumericValue(c);
            calc.push(t);
        }
        else if(c == '+'){
            x = calc.pop();
            y = calc.pop();
            r = x+y;
            calc.push(r);
        }
         else if(c == '-'){
            x = calc.pop();
            y = calc.pop();
            r = x-y;
            calc.push(r);
        }
         else if(c == '*'){
            x = calc.pop();
            y = calc.pop();
            r = x*y;
            calc.push(r);
        }
         else if(c == '/'){
            x = calc.pop();
            y = calc.pop();
            r = x/y;
            calc.push(r);
        }
    }
     }
     int a = calc.pop();
    System.out.println(a);
     }
     }