jawjaw
jawjaw

Reputation: 157

Java evaluating mathematical expressions from strings

I have strange task to do in Java. Without using any loops and if statements i have to develop simple calculator which defines all operations and numbers in one String like: "126.7214 + 121" I used regex to parse string and get 3 string variables ['125.7214', '+' ,'121'], normally i would do if statement, parseString to integer and do if statement based on math symbol to sum those numbers, but I cant. Is there any trick in Java to do it faster? Some ready-to go library? I would appreciate any advice. :code:

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Calc {

    public String doCalc(String cmd) {

        Matcher m = Pattern.compile("\\S+").matcher(cmd);
        m.find();
        String num1= m.group(0);
        m.find();
        String znak = m.group(0);
        m.find();
        String num2 = m.group(0);





        return result;
    }
}  

Upvotes: 0

Views: 6097

Answers (4)

BadIdeaException
BadIdeaException

Reputation: 2124

Here is a way that leverages polymorphy (since you already know how to parse the operands, I've left that part out because of sheer laziness on my part):

import java.util.*;

public class CalcProofOfConcept {

    public static abstract class Arithmetic { public abstract double apply(double x, double y); }

    public static class Add extends Arithmetic { public double apply(double x, double y) { return x+y; } }
    public static class Subtract extends Arithmetic { public double apply(double x, double y) { return x-y; } }
    public static class Multiply extends Arithmetic { public double apply(double x, double y) { return x*y; } }
    public static class Divide extends Arithmetic { public double apply(double x, double y) { return x/y; } }

    public static void main(String []args){
        Map<String, Arithmetic> operators = new HashMap<String, Arithmetic>();
        operators.put("+", new Add());
        operators.put("-", new Subtract());
        operators.put("*", new Multiply());
        operators.put("/", new Divide());

        double x = 125.7214;
        double y = 121;
        String op = "+";

        System.out.println(operators.get(op).apply(x,y));
    }
}

This prints 246.72140000000002.

By the way: actual arithmetic expressions are a context-free language, so for anything more than the simplest forms, using a regular expression to parse them won't work. Once you mix addition and multiplication, for instance, a regex-based calculator would give wrong results because it can't respect operator precedence.

PS: Yes, I know this is breaking a nut with a sledgehammer but I just thought it'd be a cool way to do it...

Upvotes: 0

Arman
Arman

Reputation: 655

The JavaScript parser works well for expressions.

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
public class Expression{
  public static void main(String[] args){
    ScriptEngineManager script = new ScriptEngineManager();
    ScriptEngine eng = mgr.getEngineByName("JavaScript");
    System.out.println(eng.eval("5+5*5"));
    } 
}

Upvotes: 3

J. Pichardo
J. Pichardo

Reputation: 3115

If you're not allowed to use switch and case either there are libraries that can help you:

  • EvalEx - Personally I like this one.
  • JEval
  • Commons Math: The Apache Commons Mathematics Library

Other wise you could implement a Polish Calculator

Upvotes: 2

Dale
Dale

Reputation: 1628

You could use Spring's SPeL to evaluate your values. SPeL stands for Spring Expression Language. It allows you to evaluate a String that is written in Java. The following line is an example of what you can evaluate within an expression. I imagine you could simply put your values within the expression to get the values out. Of course this isn't a fully working with all the dependencies. This example is simply showing you a simply example showing you it easily possible.

//From www.mkyong.com
Expression exp2 = parser.parseExpression("'Hello World'.length()");

Of course you can refer to the Spring site in order to learn more about how to create a Spring project with the dependencies along with several examples that are fully flushed out. I received this small snippet from the mkyong site.

http://www.mkyong.com/spring3/test-spring-el-with-expressionparser/

Upvotes: 0

Related Questions