# Math expression solver

a guest
Feb 20th, 2014
618
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
2. import java.io.IOException;
4. import java.util.ArrayList;
5. import java.util.Arrays;
6.
7. /**
8.  * Created by Vladimir on 20.02.14.
9.  */
10. public class Main {
11.     private static final ArrayList<Character> DIVIDERS = new ArrayList<Character>(Arrays.asList('*', '/', '-', '+'));
12.     private static final int RIGHT_DIRECTION = 1;
13.     private static final int LEFT_DIRECTION = -1;
14.
15.     public static void main(String[] args) {
17.         String expression = "";
18.
19.         System.out.print("Enter expression: ");
20.         try {
22.         } catch (IOException e) {
23.             e.printStackTrace();
24.         }
25.         System.out.println("Expression: " + expression);
26.
27.         expression = prepareExpression(expression);
28.
29.         System.out.println("Prepared expression: " + expression);
30.
32.
33.     }
34.
35.     //Recursive function with the state machine
36.     //states "(", "sin", "cos", "exp", "*", "/", "+", "-"
37.     private static String calc(String expression) {
38.         int pos = 0;
39.         System.out.println("Solving expression: "+expression);
40.         //Extracting expression from braces, doing recursive call
41.         //replace braced expression on result of it solving
42.         if (-1 != (pos = expression.indexOf("("))) {
43.
44.             String subexp = extractExpressionFromBraces(expression,pos);
45.             expression = expression.replace("("+subexp+")", calc(subexp));
46.
47.             return calc(expression);
48.
49.         //Three states for calculating sin cos exp
50.         //input must be like sin0.7
51.         } else if (-1 != (pos = expression.indexOf("sin"))) {
52.
53.             pos += 2;//shift index to last symbol of "sin" instead of first
54.
55.             String number = extractNumber(expression, pos, RIGHT_DIRECTION);
56.
57.             expression = expression.replace("sin"+number, Double.toString(Math.sin(Double.parseDouble(number))));
58.
59.             return calc(expression);
60.
61.         } else if (-1 != (pos = expression.indexOf("cos"))) {
62.
63.             pos += 2;
64.
65.             String number = extractNumber(expression, pos, RIGHT_DIRECTION);
66.
67.             expression = expression.replace("cos"+number, Double.toString(Math.cos(Double.parseDouble(number))));
68.
69.             return calc(expression);
70.
71.         } else if (-1 != (pos = expression.indexOf("exp"))) {
72.
73.             pos += 2;
74.
75.             String number = extractNumber(expression, pos, RIGHT_DIRECTION);
76.
77.             expression = expression.replace("exp" + number, Double.toString(Math.exp(Double.parseDouble(number))));
78.
79.             return calc(expression);
80.
81.
82.         } else if (expression.indexOf("*") > 0 | expression.indexOf("/") > 0) {
83.
84.             int multPos = expression.indexOf("*");
85.             int divPos = expression.indexOf("/");
86.
87.             pos = Math.min(multPos, divPos);
88.             if (multPos < 0) pos = divPos; else if (divPos < 0) pos = multPos; //If one value of
89.                 //*Pos will be -1 result of min will be incorrect.
90.
91.             char divider = expression.charAt(pos);
92.
93.             String leftNum = extractNumber(expression, pos, LEFT_DIRECTION);
94.             String rightNum = extractNumber(expression, pos, RIGHT_DIRECTION);
95.
96.             expression = expression.replace(leftNum + divider + rightNum, calcShortExpr(leftNum, rightNum, divider));
97.
98.             return calc(expression);
99.
100.         //парсинг выражений сложения/вычитания
101.         } else if (expression.indexOf("+") > 0 | expression.indexOf("-") > 0) {
102.
103.             int summPos = expression.indexOf("+");
104.             int minusPos = expression.indexOf("-");
105.
106.             pos = Math.min(summPos, minusPos);
107.
108.             if (summPos < 0) pos = minusPos; else if (minusPos < 0) pos = summPos;
109.
110.             char divider = expression.charAt(pos);
111.
112.             String leftNum = extractNumber(expression, pos, LEFT_DIRECTION);
113.             String rightNum = extractNumber(expression, pos, RIGHT_DIRECTION);
114.
115.             expression = expression.replace(leftNum + divider + rightNum, calcShortExpr(leftNum, rightNum, divider));
116.
117.             return calc(expression);
118.
119.         } else return expression;
120.     }
121.
122.     private static String extractExpressionFromBraces(String expression, int pos) {
123.         int braceDepth = 1;
124.         String subexp="";
125.
126.         for (int i = pos+1; i < expression.length(); i++) {
127.             switch (expression.charAt(i)) {
128.                 case '(':
129.                     braceDepth++;
130.                     subexp += "(";
131.                     break;
132.                 case ')':
133.                     braceDepth--;
134.                     if (braceDepth != 0) subexp += ")";
135.                     break;
136.                 default:
137.                     if (braceDepth > 0) subexp += expression.charAt(i);
138.
139.             }
140.             if (braceDepth == 0 && !subexp.equals("")) return subexp;
141.         }
142.         return "Failure!";
143.     }
144.
145.     private static String extractNumber(String expression, int pos, int direction) {
146.
147.         String resultNumber = "";
148.         int currPos = pos + direction;//shift pos on next symbol from divider
149.
150.     //For negative numbers
151.         if (expression.charAt(currPos) == '-') {
152.             resultNumber+=expression.charAt(currPos);
153.             currPos+=direction;
154.         }
155.
156.         for (; currPos >= 0 &&
157.                currPos < expression.length() &&
158.                !DIVIDERS.contains(expression.charAt(currPos));
159.                currPos += direction) {
160.             resultNumber += expression.charAt(currPos);
161.         }
162.
163.         if (direction==LEFT_DIRECTION) resultNumber = new StringBuilder(resultNumber).reverse().toString();
164.
165.         return resultNumber;
166.     }
167.
168.     private static String calcShortExpr(String leftNum, String rightNum, char divider) {
169.         switch (divider) {
170.             case '*':
171.                 return Double.toString(Double.parseDouble(leftNum) * Double.parseDouble(rightNum));
172.             case '/':
173.                 return Double.toString(Double.parseDouble(leftNum) / Double.parseDouble(rightNum));
174.             case '+':
175.                 return Double.toString(Double.parseDouble(leftNum) + Double.parseDouble(rightNum));
176.             case '-':
177.                 return Double.toString(Double.parseDouble(leftNum) - Double.parseDouble(rightNum));
178.             default:
179.                 return "0";
180.         }
181.
182.     }
183.
184.     private static String prepareExpression(String expression) {
185.
186.         expression = expression.replace("PI", Double.toString(Math.PI));
187.         expression = expression.replace("E", Double.toString(Math.E));
188.         expression = expression.replace(" ", "");
189.
190.         return expression;
191.     }
192. }
RAW Paste Data