3

I am trying to write a program in Java which takes input a String value like s = "1+27-63*5/3+2" and returns the calculation in integer value

Here below is my code

package numberofcharacters;
import java.util.ArrayList;
public class App {
    public static void main(String[] args) {
        String toCalculate = "123+98-79÷2*5";
        int operator_count = 0;  
        ArrayList<Character> operators = new ArrayList<>();
        for (int i=0; i < toCalculate.length(); i++){
             if (toCalculate.charAt(i) == '+' || toCalculate.charAt(i) == '-' ||
                 toCalculate.charAt(i) == '*' || toCalculate.charAt(i) == '÷' ) {
             operator_count++;  /*Calculating
                                  number of operators in a String toCalculate
                                */
             operators.add(toCalculate.charAt(i)); /* Adding that operator to 
                                                    ArrayList*/
         }
     }
     System.out.println("");
     System.out.println("Return Value :" );

     String[] retval = toCalculate.split("\\+|\\-|\\*|\\÷", operator_count + 1);    

    int num1 = Integer.parseInt(retval[0]);
    int num2 = 0;
    int j = 0;
    for (int i = 1; i < retval.length; i++) {

        num2 = Integer.parseInt(retval[i]);
        char operator = operators.get(j);
        if (operator == '+') {
            num1 = num1 + num2;

        }else if(operator == '-'){
            num1 = num1 - num2;
        }else if(operator == '÷'){
            num1 = num1 / num2;
        }else{
            num1 = num1 * num2;
        }
        j++;            
    }
    System.out.println(num1);   // Prints the result value
    }

}

****The problem is I need to perform calculation according to Order of operations in Math like Multiplication and division first , than addition and subtraction. How can I resolve this? ****

I have used String split() method to seperate the String wherever the operators "+-/*" occurs. I have used character ArrayList to add operators in it. Than at the last portion of code I am looping in that splitted array of Strings and I've initialize int num1 with the first value of splitted array of strings by parsing it to Integer. and int num2 with the second value and the using operators arraylist to perform calculation between them (whatever the operator at that index of arraylist). and storing the result in int num1 and doing vice versa until the end of the string array.

[P.S] I tried to use Collection.sort but it sorts the above arraylist of operators in that order [*, +, -, /]. It puts division at the end while it should put division after or before multiplication symbol

Ahmed Adnan
  • 165
  • 2
  • 4
  • 12
  • 1
    A usual way to deal with this is to convert your input into a prefix notation and process it using a stack. [Here's a good example](http://www.geeksforgeeks.org/expression-evaluation/) – nem035 Jan 20 '16 at 16:12
  • Why would you think sort would help here? What sort does is it rearranges the order of the items within a collection according to some ordering - which is just the lexicographical ordering for Strings by default. – Cubic Jan 20 '16 at 16:13
  • 1
    The easy way is to use ScriptEngine : http://stackoverflow.com/questions/3422673/evaluating-a-math-expression-given-in-string-form – Arnaud Jan 20 '16 at 16:13
  • I didn't really think that sort would help here. At first I was just trying to find a way to actually if java sorts operators according to order of operations in maths. – Ahmed Adnan Jan 20 '16 at 16:16
  • 1
    "*java sorts operators according to order of operations*"--There is no builtin help for this. You could write your own method to do this but the ideas presented above are better ways to accomplish the goal. – DSlomer64 Jan 20 '16 at 16:20
  • Yes I am trying ScriptEngine now. Thanks – Ahmed Adnan Jan 20 '16 at 16:22

1 Answers1

4

If you want to do it with roughly the same structure of code, and not turn it into something like reverse Polish notation first, you could try an approach that deals with the operations in reverse priority order.

So assuming that you have * and / as highest precedence, and you're treating them as equal precedence and therefore to be dealt with left-to-right; and the same for + and -; then you would

  1. Split first on + and -.
  2. Evaluate the parts that are separated by + and -, but now processing * and / in left-to-right order.
  3. Apply your + and - to these evaluated parts.

So if your expression is 3*4+5-6/2 then your code would split first into

3*4  +  5  -  6/2

Now evaluate these sub-expressions

12  +  5  -  3

Now process left-to-right to evaluate the final answer

14

In more general terms, the number of passes you'll need through your expression is determined by the number of precedence levels you have; and you need to process the precedence levels from lowest to highest. Split expression up; recursively evaluate sub-expressions just considering next precedence level and upwards; combine to get final answer.

This would be a nice little Java 8 streams exercise!

chiastic-security
  • 20,430
  • 4
  • 39
  • 67