Advertisement
Guest User

math expression evaluator

a guest
Dec 24th, 2013
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.76 KB | None | 0 0
  1. import java.util.List;
  2. import java.util.ArrayList;
  3. import java.util.LinkedList;
  4. import java.util.regex.Pattern;
  5. import java.util.regex.Matcher;
  6.  
  7. public class Calc {
  8.     public static List<Object> tokenize(String str) {
  9.         ArrayList<Object> list = new ArrayList<>();
  10.         Matcher m = Pattern.compile("[.\\d]+|[A-Za-z]+|\\S+?").matcher(str);
  11.         while(m.find()) {
  12.             String token = m.group();
  13.             try {
  14.                 list.add(Double.valueOf(token));
  15.             } catch(NumberFormatException e) {
  16.                 list.add(token);
  17.             }
  18.         }
  19.         for(int i = 0; i < list.size(); i++) {
  20.             Object o = list.get(i), p = i==0?null:list.get(i-1);
  21.             if(o.equals("+") || o.equals("-")) {
  22.                 if(p == null || !(p.equals(")") || p.equals("x") || (p instanceof Double))) {
  23.                     list.set(i, "unary" + o);
  24.                 }
  25.             }
  26.         }
  27.         return list;
  28.     }
  29.    
  30.     private static int getPriority(String operator) {
  31.         switch(operator) {
  32.             case "+": case "-": return 1;
  33.             case "*": case "/": return 2;
  34.             case "^": return 3;
  35.             case "sin": case "cos": case "tan": case "unary-": case "unary+": return 4;
  36.             case "(": return 0;
  37.         }
  38.         throw new IllegalArgumentException(operator);
  39.     }
  40.    
  41.     public static List<Object> toRPN(List<Object> input) {
  42.         ArrayList<Object> output = new ArrayList<>();
  43.         LinkedList<Object> stack = new LinkedList<>();
  44.         for(Object token: input) {
  45.             if(token instanceof Double || token.equals("x")) output.add(token);
  46.             else if(token.equals("(")) stack.push(token);
  47.             else if(token.equals(")")) {
  48.                 while(!stack.peek().equals("(")) output.add(stack.pop());
  49.                 stack.pop();
  50.             }
  51.             else {
  52.                 while(!stack.isEmpty() && getPriority((String)stack.peek()) >= getPriority((String)token)) {
  53.                     output.add(stack.pop());
  54.                 }
  55.                 stack.push(token);
  56.             }
  57.         }
  58.         while(!stack.isEmpty()) output.add(stack.pop());
  59.         return output;
  60.     }
  61.    
  62.     public static double eval(List<Object> rpn, double x) {
  63.         LinkedList<Double> stack = new LinkedList<>();
  64.         for(Object token: rpn) {
  65.             if(token instanceof Double) stack.push((Double)token);
  66.             else if(token.equals("x")) stack.push(x);
  67.             else {
  68.                 switch((String)token) {
  69.                     case "+": stack.push(stack.pop() + stack.pop()); break;
  70.                     case "-": stack.push(-stack.pop() + stack.pop()); break;
  71.                     case "*": stack.push(stack.pop() * stack.pop()); break;
  72.                     case "/": stack.push(1.0/stack.pop() * stack.pop()); break;
  73.                     case "^": double exp = stack.pop(), n = stack.pop();
  74.                               stack.push(Math.pow(n, exp)); break;
  75.                     case "unary+": break;
  76.                     case "unary-": stack.push(-stack.pop()); break;
  77.                     case "sin": stack.push(Math.sin(stack.pop())); break;
  78.                     case "cos": stack.push(Math.cos(stack.pop())); break;
  79.                     case "tan": stack.push(Math.tan(stack.pop())); break;
  80.                 }
  81.             }
  82.         }
  83.         if(stack.size() != 1) throw new RuntimeException();
  84.         return stack.pop();
  85.     }
  86.    
  87.     public static void main(String[] args) {
  88.         String str = "-3*x^2+sin(x)";
  89.         List<Object> tokens = tokenize(str);
  90.         System.out.println(tokens);
  91.         List<Object> rpn = toRPN(tokens);
  92.         System.out.println(rpn);
  93.         double result = eval(rpn, 2);
  94.         System.out.println(result);
  95.     }
  96. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement