9

Lets say I have a method that's declared this way:

public double Calc(String expression) {

// Code

}

I want to take a String expression like

"2 + 4 - (3 * 4)"

Then feed it to Calc() and it should return the value that it gets.

Can you Parse a Math Expression out of a String so that it becomes an expression that Java can understand? Because normally you could just write

return 2 + 4 - (3 * 4);

But that would only work for that single expression.

OmniOwl
  • 5,477
  • 17
  • 67
  • 116
  • Take a look at this: http://stackoverflow.com/questions/2605032/using-eval-in-java – Alberto Segura Feb 26 '13 at 09:03
  • 1
    To roll your own you'd normally use an expression tree http://en.wikipedia.org/wiki/Binary_expression_tree – Daniel Imms Feb 26 '13 at 09:04
  • @beto But it seems that doing this, you open up the entire JS engine just to do this one thing. Though it gave me a hint I suppose. Thanks! – OmniOwl Feb 26 '13 at 09:06
  • What about using regular expressions to simplify the solution using BODMAS principle and executing the statement. You can iterate through the expression using a loop. Evaluate each of the conditions and finally throw out the answer. JS method is not good as injections are a real threat to your app. – Shouvik Feb 26 '13 at 09:09
  • @Shouvik I do not know BODMAS Principle. I guess I'll have to google that. – OmniOwl Feb 26 '13 at 09:11
  • http://en.wikipedia.org/wiki/Order_of_operations – Shouvik Feb 26 '13 at 09:12
  • @Shouvik Oh right. Yeah okay, I thought it was something else. I know the order in which you calculate an operation, but I can't see how it would make it an easy thing to write in Java, seeing as the loops would have to consider a lot of things I guess. Like brackets in brackets, and just brackets first in general. Multiplication before addition etc. – OmniOwl Feb 26 '13 at 09:13
  • Well, best of luck with that! :) [NOM] This question seems relevant: http://stackoverflow.com/questions/114586/smart-design-of-a-math-parser?rq=1 – Shouvik Feb 26 '13 at 09:17
  • 2
    Google "evaluate infix expression" and you'll find your answer. – Benoît Guédas Feb 26 '13 at 09:20
  • have a look at this http://floris.briolas.nl/floris/2008/07/simple-calculator-with-antlr/ – user902383 Feb 26 '13 at 09:43

2 Answers2

7

I would suggest using Dijkstra's twostack algorithm.

This should be pretty much what you need:

public class DijkstraTwoStack {
    public static void main(String[] args) {
                Scanner scanner = new Scanner(System.in);
                String exp[] = scanner.nextLine().split(" ");
        Stack<String> ops = new Stack<String>();
        Stack<Double> vals = new Stack<Double>();

        for(int i = 0; i < exp.length; i++) {
                        String s = exp[i];
            if (s.equals("(")) {
            }
            else if (s.equals("+") || s.equals("*")) {
                ops.push(s);
            } else if (s.equals(")")) {
                getComp(ops, vals);
            } else {
                vals.push(Double.parseDouble(s));
            }
        }
        getComp(ops, vals);
        System.out.println(vals.pop());
    }

    private static void getComp(Stack<String> ops, Stack<Double> vals) {
        String op = ops.pop();
        if (op.equals("+")) {
            vals.push(vals.pop() + vals.pop());
        } else if (op.equals("*")) {
            vals.push(vals.pop() * vals.pop());
        }
    }
}

Haven't tested it, but it should be about right.

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
  • Not so efficient, but one can use this .... `ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("js"); Object result = engine.eval("3+4");` *credits : http://stackoverflow.com/a/2605051/936786 – Jyoti Ranjan Feb 06 '14 at 11:57
  • Please don't change the code from existing answers. No iterator was wanted, it would break the algorithm. – Jeroen Vannevel Feb 06 '14 at 11:59
0

Let me state is as an answer a process which could be adopted as I think though browsing over a couple of questions on SO you should get a fair idea on how to do this without loading a JS compiler.

For starters you need to parse your string through a function that converts your math string to a infix string. Then this you basically evaluate this expression as another function by breaking down the string in a loop to return your answer. A beautifully detailed process can be found here.

Shouvik
  • 11,350
  • 16
  • 58
  • 89