Guest User

Math expression solver

a guest
Feb 20th, 2014
618
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  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) {
  16.         BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
  17.         String expression = "";
  18.  
  19.         System.out.print("Enter expression: ");
  20.         try {
  21.             expression = reader.readLine();
  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.  
  31.         System.out.println("Answer: " + calc(expression));
  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