-2

I need to evaluate a mathematical expression in Java.

The problem is, the expression is a String object.

Is there a way to take the string "( (21 + 3) / 4 )" and evaluate it so that it gives 6 as a result?

This is the code so far.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

class InfixApp
{
    public static void main(String[] args) throws IOException
    {
        String input, output;
            while(true)
            {
                System.out.print("Enter infix: ");
                System.out.flush();
                input = getString(); // read a string from kbd
                if( input.equals("") ) // quit if [Enter]
                    break;
                // make a translator
                InToPost theTrans = new InToPost(input);
                output = theTrans.doTrans(); // do the translation
                System.out.println("Postfix is " + output + '\n');
            } // end while
    } // end main()
    //--------------------------------------------------------------
    public static String getString() throws IOException
    {
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(isr);
        String s = br.readLine();
        return s;
    }

} // end class InfixApp
class InToPost // infix to postfix conversion
{
    private StackX theStack;
    private String input;
    private String output = "";
    //--------------------------------------------------------------
    public InToPost(String in) // constructor
    {
        input = in;
        int stackSize = input.length();
        theStack = new StackX(stackSize);
    }
    //--------------------------------------------------------------
    public String doTrans() // do translation to postfix
    {
        for(int j=0; j<input.length(); j++)
        {
            char ch = input.charAt(j);
            theStack.displayStack("For "+ch+" "); // *diagnostic*
            switch(ch)
            {
                case '+': // its + or -    
                case '-':   
                    gotOper(ch, 1); // go pop operators
                    break; // (precedence 1)

                case '*': // its * or / or $
                case '/':
                case '$':
                    gotOper(ch, 2); // go pop operators
                    break; // (precedence 2)

                case '(': // its a left paren
                theStack.push(ch); // push it
                break;

                case ')': // its a right paren
                    gotParen(ch); // go pop operators
                    break;              

                default: // must be an operand
                    output = output + ch ; // write it to output
                break;

             }// end switch
        } // end for
        while( !theStack.isEmpty() ) // pop remaining opers
        {
            theStack.displayStack("While "); // *diagnostic*
            output += theStack.pop() + " "; // write to output
        }
        theStack.displayStack("End "); // *diagnostic*
        return output; // return postfix
    } // end doTrans()
    //--------------------------------------------------------------
    public void gotOper(char opThis, int prec1)
    { // got operator from input
        while( !theStack.isEmpty() )
        {
        char opTop = theStack.pop();
        if( opTop == '(' ) // if its a (
        {
            theStack.push(opTop); // restore (
            break;
        }
        else // its an operator
        {
            int prec2; // precedence of new op
            if(opTop== '+' || opTop == '-' ) // find new op prec
                prec2 = 1;
            else
                prec2 = 2;
            if(prec2 < prec1) // if prec of new op less
            { // than prec of old
                theStack.push(opTop); // save newly-popped op
                break;
            }
            else // prec of new not less
                output = output + opTop; // than prec of old
        } // end else (its an operator)
    } // end while
    theStack.push(opThis); // push new operator
    } // end gotOp()
    //--------------------------------------------------------------
    public void gotParen(char ch)
    { // got right paren from input
        while( !theStack.isEmpty() )
        {
            char chx = theStack.pop();
            if( chx == '(' ) // if popped (
                break; // were done
            else // if popped operator
                output = output + chx; // output it
        } // end while
    } // end popOps()
    //--------------------------------------------------------------
} // end class InToPost
import java.io.*; // for I/O
class StackX
{
    private int maxSize;
    private char[] stackArray;
    private int top;
//--------------------------------------------------------------
public StackX(int s) // constructor
{
    maxSize = s;
    stackArray = new char[maxSize];
    top = -1;
}
//--------------------------------------------------------------
public void push(char j) // put item on top of stack
    { stackArray[++top] = j; }
//--------------------------------------------------------------
public char pop() // take item from top of stack
    { return stackArray[top--]; }
//--------------------------------------------------------------
public char peek() // peek at top of stack
    { return stackArray[top]; }
//--------------------------------------------------------------
public boolean isEmpty() // true if stack is empty
    { return (top == -1); }
//-------------------------------------------------------------
public int size() // return size
    { return top+1; }
//--------------------------------------------------------------
public char peekN(int n) // return item at index n
    { return stackArray[n]; }
//--------------------------------------------------------------
public void displayStack(String s)
{
    System.out.print(s);
    System.out.print("Stack (bottom-->top): ");
    for(int j=0; j<size(); j++)
    {
        System.out.print( peekN(j) );
        System.out.print(" ");
    }
    System.out.println(" ");
}
} // end class StackX
fabian
  • 80,457
  • 12
  • 86
  • 114
vieuxdats
  • 19
  • 5
  • Some options: 1. Use a formula parser and execute the content of the `String` there. 2. Use a javascript engine and evaluate the expression. – Luiggi Mendoza Mar 26 '15 at 21:08
  • Not without lots of other work around it. You could fire up [Rhino](http://docs.oracle.com/javase/7/docs/technotes/guides/scripting/programmer_guide/) and evaluate it, but that feels a bit heavy for such. –  Mar 26 '15 at 21:08
  • 3
    _cast_ is not the correct term for this, _evaluate_ would be better. – GriffeyDog Mar 26 '15 at 21:10
  • ... well now, that is a *completely* different problem that originally asked. –  Mar 26 '15 at 21:12

2 Answers2

2

You can use ScriptEngine:

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "( (21 + 3) / 4 ) ";
try {
    System.out.println(engine.eval(foo));
} catch (ScriptException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
Laerte
  • 7,013
  • 3
  • 32
  • 50
0

Disclaimer: this answer is only valid if you intend to do the stuff yourself. If you are looking for a quick/efficient way to do this kind of parsing, it's certainly better to use some tool/library as proposed in other answers...

You have a program that transforms infix notation to postfix notation. For instance:

infix: ( ( 21 + 3 ) / 4 )

should output something like:

postfix: 21 3 + 4 /

Now if you want to evaluate this expression, the postfix notation is quite easy: when reading token from the left to the right, you just have to stack operands (21, 3, ...) until an operator (+, /) is found. Then you pop the stack, apply the operator and stack the result.

  • init
    • stack: [], expr: 21 3 + 4 /
  • read 21, stack it:
    • stack: [21], expr: 3 + 4 /
  • read 3, stack it:
    • stack: [21 3], expr: + 4 /
  • read +, pop 3 and 21, add and stack result 24
    • stack: [24], expr: 4 /
  • read 4, stack it
    • stack: [24 4], expr: /
  • read /, pop 4 and 24, divide and stack result 6
    • stack: [6], expr: .

When there is no more token to read, the stack contains the final result.

T.Gounelle
  • 5,953
  • 1
  • 22
  • 32