0

I wrote the following program. My program can provide simple arithmetic calculation like +, -, *, / from the value of JTextField. But i need to get answer with operator precedence BMDAS (Brackets, Multiplication, Division, Addition and Subtraction) from multiple values. example: user types 10-5+8/56*(3-5+3): answer is 5. I mention my implementation code. how can i update my program to get the above requirement? help me!

    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JTextField;

public class calculateValue extends JFrame implements ActionListener{

    private JButton btn;
    private JTextField txt;
    String operator="+-*/()";

    public static void main(String args[]){
        new calculateValue();
    }

    public calculateValue(){
        setSize(300, 200);
        setLocationRelativeTo(null);
        setTitle("Calcuate Multiple value!");
        setLayout(null);

        txt=new JTextField();
        txt.setBounds(20,20, 150,25);
        add(txt);

        btn=new JButton("Show Answer");
        btn.setBounds(20, 50,150, 25);
        btn.addActionListener(this);
        add(btn);

        setVisible(true);
    }


    public char decideOperator(String s){
        char c=' ';

        for(int i=0;i<operator.length();i++){

            if(s.contains(operator.charAt(i)+"")){
                c=operator.charAt(i);   
            }
        }
        return c;
    }

    public int decideIndex(String s){
        int index=100;
        for(int i=0;i<operator.length();i++){

            if(s.contains(operator.charAt(i)+"")){
                index=s.indexOf(operator.charAt(i));
            }
        }
        return index;
    }

    public void actionPerformed(ActionEvent e){
        String temp=txt.getText().trim();

        double d1=Double.parseDouble(temp.substring(0, decideIndex(temp)));
        double d2=Double.parseDouble(temp.substring(decideIndex(temp)+1));

        if(decideOperator(temp)=='+') System.out.println(d1+d2);
        else if(decideOperator(temp)=='-') System.out.println(d1-d2);
        if(decideOperator(temp)=='*') System.out.println(d1*d2);
        if(decideOperator(temp)=='/') System.out.println(d1/d2);

    }
}
BackSlash
  • 21,927
  • 22
  • 96
  • 136
user2729868
  • 17
  • 1
  • 1
  • 5
  • 3
    **Side note:** `setLayout(null);` is a bad practice, use [Layout Managers](http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html) instead, they can save you a lot of work. – BackSlash Sep 03 '13 at 12:33
  • possible duplicate of [Java: Parse a mathematical expression given as a string and return a number](http://stackoverflow.com/questions/1432245/java-parse-a-mathematical-expression-given-as-a-string-and-return-a-number) – z - Sep 03 '13 at 12:39
  • http://stackoverflow.com/questions/3422673/evaluating-a-math-expression-given-in-string-form You could just evaluate the String that the user inputs – Ben Dale Sep 03 '13 at 12:46
  • I'd use the `ScriptEngine` for this one, as seen in [this answer](http://stackoverflow.com/a/7441804/418556). – Andrew Thompson Sep 03 '13 at 12:49
  • i want to calculate by using operators and methods! – user2729868 Sep 03 '13 at 12:59
  • Try building an expression in a tree structure from your input, and then evaluating it. – vikingsteve Sep 03 '13 at 13:00

2 Answers2

1

This may seem a bit excessive but here is my implementation of a expression resolver:

(Given as a SSCCE):

import java.math.BigDecimal;

public class Main {
    public static void main(String[] args) throws Exception{
        System.out.println("Final Output: " + evalutateExpression("(56*3)*(4+3)"));
    }

    public static double evalutateExpression(String Input){
        //This method is extremely sensitive to bad input, try to do some clean up before sending it to the main evaluation body.
        Input = Input.replaceAll(" ", ""); //Example of a cleanup

        return Double.parseDouble(recursiveEvalutation(Input));
    }

    private static String recursiveEvalutation(String I){
        if(I.contains("(")){
            int RIndex = I.indexOf(")");
            int LIndex = I.lastIndexOf("(", RIndex);
            return recursiveEvalutation(I.substring(0, LIndex) + recursiveEvalutation(I.substring(LIndex + 1, RIndex)) + I.substring(RIndex + 1, I.length()));
        }else if(I.contains("^") || I.contains("√")){
            int PowerIndex = I.indexOf("^");
            int SQRTIndex = I.indexOf("√");

            if(PowerIndex == -1){
                PowerIndex = Integer.MAX_VALUE;
            }
            if(SQRTIndex == -1){
                SQRTIndex = Integer.MAX_VALUE;
            }

            if(PowerIndex <= SQRTIndex){
                int num2End = findNumberEnd(I.substring(PowerIndex + 1, I.length())) + PowerIndex + 1;
                int num1Start = findNumberStart(I.substring(0, PowerIndex));

                double Num1 = Double.parseDouble(I.substring(num1Start, PowerIndex));
                double Num2 = Double.parseDouble(I.substring(PowerIndex + 1, num2End));

                String Eval = new BigDecimal(Math.pow(Num1, Num2)).toPlainString();

                return recursiveEvalutation(I.substring(0, num1Start) + Eval + I.substring(num2End, I.length()));
            }else{
                int num2End = findNumberEnd(I.substring(SQRTIndex + 1, I.length())) + SQRTIndex + 1;
                int num1Start = findNumberStart(I.substring(0, SQRTIndex));

                double Num1 = Double.parseDouble(I.substring(SQRTIndex + 1, num2End));

                String Eval = new BigDecimal(Math.sqrt(Num1)).toPlainString();

                return recursiveEvalutation(I.substring(0, num1Start) + Eval + I.substring(num2End, I.length()));
            }
        }else if(I.contains("*") || I.contains("/")){
            int MultiplyIndex = I.indexOf("*");
            int DivideIndex = I.indexOf("/");

            if(MultiplyIndex == -1){
                MultiplyIndex = Integer.MAX_VALUE;
            }
            if(DivideIndex == -1){
                DivideIndex = Integer.MAX_VALUE;
            }

            if(MultiplyIndex <= DivideIndex){
                int num2End = findNumberEnd(I.substring(MultiplyIndex + 1, I.length())) + MultiplyIndex + 1;
                int num1Start = findNumberStart(I.substring(0, MultiplyIndex));
                double Num1 = Double.parseDouble(I.substring(num1Start, MultiplyIndex));
                double Num2 = Double.parseDouble(I.substring(MultiplyIndex + 1, num2End));

                String Eval = new BigDecimal(Num1 * Num2).toPlainString();

                return recursiveEvalutation(I.substring(0, num1Start) + Eval + I.substring(num2End, I.length()));
            }else{
                int num2End = findNumberEnd(I.substring(DivideIndex + 1, I.length())) + DivideIndex + 1;
                int num1Start = findNumberStart(I.substring(0, DivideIndex));
                double Num1 = Double.parseDouble(I.substring(num1Start, DivideIndex));
                double Num2 = Double.parseDouble(I.substring(DivideIndex + 1, num2End));

                String Eval = new BigDecimal(Num1 / Num2).toPlainString();

                return recursiveEvalutation(I.substring(0, num1Start) + Eval + I.substring(num2End, I.length()));
            }
        }else if(I.contains("+") || I.contains("−")){
            int AddIndex = I.indexOf("+");
            int MinusIndex = I.indexOf("−");

            if(AddIndex == -1){
                AddIndex = Integer.MAX_VALUE;
            }
            if(MinusIndex == -1){
                MinusIndex = Integer.MAX_VALUE;
            }

            if(AddIndex <= MinusIndex){
                int num2End = findNumberEnd(I.substring(AddIndex + 1, I.length())) + AddIndex + 1;
                int num1Start = findNumberStart(I.substring(0, AddIndex));
                double Num1 = Double.parseDouble(I.substring(num1Start, AddIndex));
                double Num2 = Double.parseDouble(I.substring(AddIndex + 1, num2End));

                String Eval = new BigDecimal(Num1 + Num2).toPlainString();

                return recursiveEvalutation(I.substring(0, num1Start) + Eval + I.substring(num2End, I.length()));
            }else{
                int num2End = findNumberEnd(I.substring(MinusIndex + 1, I.length())) + MinusIndex + 1;
                int num1Start = findNumberStart(I.substring(0, MinusIndex));

                double Num1 = Double.parseDouble(I.substring(num1Start, MinusIndex));
                double Num2 = Double.parseDouble(I.substring(MinusIndex + 1, num2End));

                String Eval = new BigDecimal(Num1 - Num2).toPlainString();

                return recursiveEvalutation(I.substring(0, num1Start) + Eval + I.substring(num2End, I.length()));
            }
        }else{
            return I;
        }
    }

    private static int findNumberEnd(String I){
        char[] expression = I.toCharArray();

        for(int x = 0;x < expression.length;x++){
            if(!Character.isDigit(expression[x]) && expression[x] != '.' && expression[x] != '-'){
                return x;
            }
        }

        return expression.length;
    }

    private static int findNumberStart(String I){
        char[] expression = I.toCharArray();

        for(int x = expression.length - 1;x >= 0;x--){
            if(!Character.isDigit(expression[x]) && expression[x] != '.' && expression[x] != '-'){
                return x + 1;
            }
        }

        return 0;
    }
}

Follows a recursive procedure to continuously evaluate expressions left and right of the operator following operator precedence. The main evaluator being the recursiveEvalutation() method.

Limitations include:

  • Undefined behavior if output reaches infinity.
  • Extremely intensive (creates many many objects, especially strings)

Note that for subtraction, I am using a proper "minus sign" for the operation and a hyphen for negative numbers.

Study the code for a bit, if you have any questions feel free to ask.

initramfs
  • 8,275
  • 2
  • 36
  • 58
0

You will need to use either Reverse Polish Notation for parsing and preparing your expresion for calculation (it uses stack to order resolve mathematical operations precedence), or (easy solution) check the answer provided in following SO post How to parse a mathematical expression given as a string and return a number?

Community
  • 1
  • 1
Antoniossss
  • 31,590
  • 6
  • 57
  • 99