How to calculate mathematical expressions in a string?

Asked

Viewed 5,444 times

17

I’m making an application picks up an expression. How do I calculate the result of an expression? For example: 3(-9)+50/2. This expression is typed in TextView.

  • 1

    This is a response more focused on the conversion and manipulation of a certain variable, is not something exclusive to Android. What this TextView returns? A String? You can make the question less platform-independent and useful to you: "How to calculate mathematical expressions in a String?". ps: just opinion.

  • 1

    I also agree @Renan, I think the only limitation would be the Java language, any answer that solves the problem is valid. There may even be good answers.

  • 1

    @Renan Yes I agree with everything, but what appears is that he has no knowledge of Java and that maybe for him Java is part of Android, so it is not even by bad, but rather by lack of knowledge only.

3 answers

12


To capture the value of TextView you must use the method getText() and convert to string using toString()

TextView myTextView;
...
String data = myTextView.getText().toString();

Parse and evaluate with expr

You can use the expr package (https://github.com/darius/expr), this package interprets and calculates the mathematical expressions over floating point numbers, such as 2 + 2 or cos(x/(2*pi)) * cos(y/(2*pi))

  1. Installing:

    To install import the package expr.jar for your project (you will need to compile the .java first if you download from Github. If you don’t have the make, then run the following command in the folder you downloaded from Github run javac -O expr/*.java and then jar cf expr.jar expr/*.class.)

  2. Adding to Activity:

    To use the package you can include it in MainActivity.java (or to another Activity) using like this import exp; (or something similar)

  3. Using:

    To use with the TextView, would be something like:

    String data = myTextView.getText().toString();
    
    try {
        expr = Parser.parse(data);
        myTextView.setText(expr.value());
    } catch (SyntaxException e) {
        myTextView.setText(e.explain());
    }
    

Scriptengine

As the user said @Walkin (using Javascript engine can be overkill for a "simple" task), but still you can use it.

The ScriptEngine is an Ecmascript/Javascript engine to perform the calculation/operation, according to Soen, you will have to use the javax.script.*, which is available from the JDK1.6.

Example with TextView:

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
...

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");

String data = myTextView.getText().toString();
System.out.println(engine.eval(data));

To set your own TextView or to another TextView, use:

TextView myTextView;
...
String data = myTextView.getText().toString();
myTextView.setText(engine.eval(data));
  • 1

    Agreeing with the first comment of the reference, I think that using a Javascript engine to solve this problem, is the same thing as a cannon to kill an ant, where a simple parser of expressions solves hehe. Another problem is that any JS expression is valid, even though it is not mathematically valid. Maybe it’s worth more just doing a parser for learning too.

12

You need to build a appraiser of mathematical expressions. I did one in C, but it was for reverse polish notation (which I don’t know if it suits you).

The TextBox will have to return a string which is the expression that needs to be evaluated, so you basically read the line of text and as you go finding an operator or number, you keep it in a stack/tree to be able to perform the operations in the proper order, for example: 1 + (2 * 5).

  • You read the first item: 1 is a number, so put it in the stack.
  • You read the second item: + is an operator that will be executed with the 1, stack of operators.
  • You read the third item: ( - parentheses - so here comes a new expression that I must evaluate before returning the result to operate with the previous one - opens a branch in the decision tree.
  • you read the fourth item: 2 is a number so put on the new stack.
  • you read the fifth item: * is an operator - puts in the stack of operators, will be executed with the 2.
  • you read the last item: ) - parentheses, is the last and closes a branch of the tree, so you pull the stack and solve the expressions.

I don’t know if you got it right, but it’s basically a data structure exercise (piles and trees) where you find expressions that will operate 2 in sequence.

The precedence of operators, is the mathematics that says and the trees are bifurcations of the nested expressions. If an operator or parentheses are missing, the tree/stack will be incomplete and the expression automatically fails.

If I’m not mistaken, you can represent this as a Deterministic Finite Automaton, I can’t remember exactly.

A code I found on the net:

http://www.vivaolinux.com.br/script/Avaliacao-de-expressoes-matematicas

  • In the part where it says "pulling the stack and solving the expressions". How would it be to know in what order an item from these stacks should be pulled? For example, you pulled "1" (stack of numbers). Then what action should be taken? Get the next item in the stack of numbers or in the operators? How to do this check?

  • The pile and the tree are the order itself. Think about it, in a stack the first one that comes in is the last one that comes out, so you would solve the expression from the last one to the first one, when the stack is empty, it has been solved. So every "pop-up" you’re getting closer to the end of the expression, another hint is that operators are usually binary, they always need 2 elements to run, so you don’t necessarily need a stack or more than one, can use a binary tree too, the order is still from the end of the tree to the first in.

  • 1

    I know the answer is very old, but even so, I have to comment that a deterministic finite automaton does not serve for this, it has to be a pushdown automaton. The reason for this is that a finite automaton is not able to remember which are the open parentheses or where they opened.

5

Browser other questions tagged

You are not signed in. Login or sign up in order to post.