Eddy
Eddy

Reputation: 1

Java - How to use a hashmap to map simple math operators

I have to create a program to simulate a calculator. We have to use a hashmap in the Operator class but I'm not sure how to go about this. The basic logic as I understand it is. We send the program a simple expression such as 1+2-3*4/5 . Then The program will divide this into two stacks. One with Operators and one with Operands. When dividing the characters we have to check the hashmap for the Operator and then push it to the stack and this is where I'm stuck. How/Where do I place/use the hashmap? My code is as follows:

import java.util.*;

public class Evaluator {

    private Stack<Operand> opdStack;
    private Stack<Operator> oprStack;

    public Evaluator() {
        opdStack = new Stack<Operand>();
        oprStack = new Stack<Operator>();
    } // end constructor

    public int eval(String expr) {
        String tok;
        expr = expr + "!";

        String delimiters = "+-*/#! ";
        StringTokenizer st = new StringTokenizer(expr, delimiters, true);

        while (st.hasMoreTokens()) {
            tok = st.nextToken();
            if(!tok.equals(" ")) {
                if(Operand.check(tok)){
                    opdStack.push(new Operand(tok));
                }
                else{
                    if (!Operator.check(tok)) {
                        System.out.println("*****invalid token******\n");
                        System.exit(1);
                    } // end if
                } // end else
            } // end if
        } // end while
        return 0;
    } // end eval
} // end Evaluator

abstract class Operator {

    static HashMap operators = new HashMap();

    public abstract int priority();

    static boolean check(String tok) {
        boolean result = false;
        operators.put("#", new PoundOperator());
        operators.put("!", new ExclamationOperator());
        operators.put("+", new AdditionOperator());
        operators.put("-", new SubtractionOperator());
        operators.put("*", new MultiplicationOperator());
        operators.put("/", new DivisionOperator());

        if (operators.containsKey(tok)) {
            result = true;
        }
        return result;
    } // end check

    public abstract Operand execute(Operand opd1, Operand opd2);

} // end Operator

Any help/clarification is deeply appreciated. Thank you.

Upvotes: 0

Views: 3083

Answers (1)

Dave
Dave

Reputation: 4291

Several things...

1) The HashMap class is generic and can take type parameters to make it a bit easier to use: HashMap<String, Operator>.

2) You are adding new instances of Operators to your hash map every time you call the check method. Those instances simply overwrite the old instances, but that is not the behavior you intend. Initialization of the hash map (all the operators.put statements) should occur in a static initializer. That way, it only happens once.

3) You need to retrieve the Operator from the hash map at the point where your really long comment ("Here I check...") currently is. How can that happen? Well, the operators map is only package private, so you could potentially just use Operator.operators.get directly, but I would imagine that is not the intention. I believe you want a separate static getter method in the Operator class, something like:

abstract class Operator {
    ...
    static Operator get(String token) {
        return operators.get(token);
    }
    ...
}

With that, you should just be able to push the Operator onto your stack with a call like oprStack.push(Operator.get(tok));.

Upvotes: 1

Related Questions